<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="keywords" content="imlgw,半岛铁盒,blog,Java博客,程序员,个人博客,java開發,程序員,個人博客,Java">
    <meta name="description" content="大悲无泪，大悟无言，大笑无声。">
    <meta name="author" content="Resolmi">
    
    <title>
        
            LeetCode二叉树 |
        
        Tadow
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    <link rel="shortcut icon" href="https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico">
    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/css/font-awesome.min.css">
    <script id="hexo-configurations">
    let KEEP = window.KEEP || {};
    KEEP.hexo_config = {"hostname":"imlgw.top","root":"/","language":"zh-CN","path":"search.json"};
    KEEP.theme_config = {"toc":{"enable":true,"number":true,"expand_all":true,"init_open":true},"style":{"primary_color":"#0066CC","avatar":"https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png","favicon":"https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico","article_img_align":"left","left_side_width":"260px","content_max_width":"920px","hover":{"shadow":false,"scale":true},"first_screen":{"enable":true,"background_img":"/images/image.svg","description":"Keep It Simple & Stupid."},"scroll":{"progress_bar":{"enable":true},"percent":{"enable":true}}},"local_search":{"enable":true,"preload":false},"code_copy":{"enable":true,"style":"default"},"pjax":{"enable":true},"lazyload":{"enable":true},"version":"3.4.3"};
    KEEP.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 月前","year":"%s 年前"};
  </script>
<meta name="generator" content="Hexo 5.4.0"><link rel="stylesheet" href="/css/prism.css" type="text/css"></head>


<body>
<div class="progress-bar-container">
    
        <span class="scroll-progress-bar"></span>
    

    
        <span class="pjax-progress-bar"></span>
        <span class="pjax-progress-icon">
            <i class="fas fa-circle-notch fa-spin"></i>
        </span>
    
</div>


<main class="page-container">

    

    <div class="page-main-content">

        <div class="page-main-content-top">
            <header class="header-wrapper">

    <div class="header-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                Tadow
            </a>
        </div>

        <div class="right">
            <div class="pc">
                <ul class="menu-list">
                    
                        <li class="menu-item">
                            <a class=""
                               href="/"
                            >
                                首页
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/archives"
                            >
                                归档
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/categories"
                            >
                                分类
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/sbe"
                            >
                                订阅
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/links"
                            >
                                友链
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/about"
                            >
                                关于
                            </a>
                        </li>
                    
                    
                        <li class="menu-item search search-popup-trigger">
                            <i class="fas fa-search"></i>
                        </li>
                    
                </ul>
            </div>
            <div class="mobile">
                
                    <div class="icon-item search search-popup-trigger"><i class="fas fa-search"></i></div>
                
                <div class="icon-item menu-bar">
                    <div class="menu-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="header-drawer">
        <ul class="drawer-menu-list">
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/">首页</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/archives">归档</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/categories">分类</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/sbe">订阅</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/links">友链</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/about">关于</a>
                </li>
            
        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="page-main-content-middle">

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="article-content-container">

        <div class="article-title">
            <span class="title-hover-animation">LeetCode二叉树</span>
        </div>

        
            <div class="article-header">
                <div class="avatar">
                    <img src="https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png">
                </div>
                <div class="info">
                    <div class="author">
                        <span class="name">Resolmi</span>
                        
                            <span class="author-label">BOSS</span>
                        
                    </div>
                    <div class="meta-info">
                        <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fas fa-edit"></i>&nbsp;2019-11-06 00:00:00
    </span>
    
        <span class="article-categories article-meta-item">
            <i class="fas fa-folder"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/%E7%AE%97%E6%B3%95/">算法</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fas fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/LeetCode/">LeetCode</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E4%BA%8C%E5%8F%89%E6%A0%91/">二叉树</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
        <span class="article-wordcount article-meta-item">
            <i class="fas fa-file-word"></i>&nbsp;<span>40.1k 字</span>
        </span>
    
    
        <span class="article-min2read article-meta-item">
            <i class="fas fa-clock"></i>&nbsp;<span>181 分钟</span>
        </span>
    
    
        <span class="article-pv article-meta-item">
            <i class="fas fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

                    </div>
                </div>
            </div>
        

        <div class="article-content markdown-body">
            <h2 id="LeetCode-二叉树"><a href="#LeetCode-二叉树" class="headerlink" title="LeetCode 二叉树"></a><em>LeetCode 二叉树</em></h2><blockquote>
<p>善用<strong>ctrl+f</strong></p>
</blockquote>
<h2 id="144-二叉树的前序遍历"><a href="#144-二叉树的前序遍历" class="headerlink" title="144. 二叉树的前序遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-preorder-traversal/" >144. 二叉树的前序遍历<i class="fas fa-external-link-alt"></i></a></h2><p>Given a binary tree, return the <em>preorder</em> traversal of its nodes’ values.</p>
<p><strong>Example:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">   <span class="number">1</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">2</span></span><br><span class="line">    /</span><br><span class="line">   <span class="number">3</span></span><br><span class="line"></span><br><span class="line">Output: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br></pre></td></tr></table></figure>

<p><strong>Follow up:</strong> Recursive solution is trivial, could you do it iteratively?</p>
<p><strong>解法一</strong></p>
<p>递归，没啥好说的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">preorderTraversal</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        res.add(root.val);</span><br><span class="line">        preorderTraversal(root.left);</span><br><span class="line">        preorderTraversal(root.right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>教科书上的写法，经典的前序遍历非递归实现方式</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">preorderTraversal</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    stack.push(root);</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        TreeNode top=stack.pop();</span><br><span class="line">        res.add(top.val);</span><br><span class="line">        <span class="comment">//注意顺序</span></span><br><span class="line">        <span class="keyword">if</span> (top.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            stack.push(top.right);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (top.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            stack.push(top.left);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法三</strong></p>
<p>非递归，模拟递归栈的方式，记录节点以及是否需要继续寻找子节点</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">preorderTraversal</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;Command&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    stack.push(<span class="keyword">new</span> Command(<span class="keyword">true</span>,root));</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        Command command=stack.pop();</span><br><span class="line">        <span class="keyword">if</span> (!command.isGo) &#123;</span><br><span class="line">            res.add(command.node.val);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            TreeNode node=command.node;</span><br><span class="line">            <span class="comment">//逆序进栈</span></span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                stack.push(<span class="keyword">new</span> Command(<span class="keyword">true</span>,node.right));</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                stack.push(<span class="keyword">new</span> Command(<span class="keyword">true</span>,node.left));</span><br><span class="line">            &#125;    </span><br><span class="line">            stack.push(<span class="keyword">new</span> Command(<span class="keyword">false</span>,node));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">Command</span></span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span>  isGo; <span class="comment">//是否继续寻找子节点</span></span><br><span class="line">    TreeNode node; <span class="comment">//当前节点</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Command</span><span class="params">(<span class="keyword">boolean</span> isGo,TreeNode node)</span></span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.isGo=isGo;</span><br><span class="line">        <span class="keyword">this</span>.node=node;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>bobo老师的一种思路，可以说是相当妙了👏，一下就解决了三种遍历的非递归实现，另外两种只需要调整一下进栈的顺序就可以了！</p>
<p><strong>解法四</strong></p>
<p>找到一个板子，可以很好的解决三种遍历</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//经典的非递归实现方式</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">preorderTraversal4</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">while</span>(cur!=<span class="keyword">null</span>||!stack.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">while</span> (cur!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            res.add(cur.val);</span><br><span class="line">            stack.push(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//没有左子树了</span></span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        <span class="comment">//切换为右子树</span></span><br><span class="line">        cur=cur.right;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>关于 <code>while(cur!=null||!stack.isEmpty())</code>，其实栈中存的只是某一个根节点的所有左子树，并不是所有的节点，所以栈为空不代表已经遍历完所有节点了，只能代表当前节点的左子树都遍历完了，还有右子树还没遍历，只有当右子树也为空也就是<code>cur==null</code> 的时候才是遍历完了，具体看一下下面这颗树就明白了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">      <span class="number">5</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">4</span>    <span class="number">6</span> </span><br><span class="line">  /      \</span><br><span class="line"><span class="number">3</span>       <span class="number">8</span></span><br></pre></td></tr></table></figure>


</blockquote>
<h2 id="589-N叉树的前序遍历"><a href="#589-N叉树的前序遍历" class="headerlink" title="589. N叉树的前序遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/" >589. N叉树的前序遍历<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个 N 叉树，返回其节点值的<em>前序遍历</em>。</p>
<p>例如，给定一个 <code>3叉树</code> :</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s2.ax1x.com/2019/11/20/MWwEt0.png"
                      alt="MWwEt0.png"
                ></p>
<p>返回其前序遍历: <code>[1,3,5,6,2,4]</code>。</p>
<p><strong>说明:</strong> 递归法很简单，你可以使用迭代法完成此题吗?</p>
<p><strong>解法一</strong></p>
<p>递归没啥好说的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//递归的方式</span></span><br><span class="line">List&lt;Integer&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">preorder</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    List&lt;Node&gt; children=root.children;</span><br><span class="line">    res.add(root.val);</span><br><span class="line">    <span class="keyword">for</span> (Node node:children) &#123;</span><br><span class="line">        preorder(node);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>迭代的方式</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">preorder</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    Stack&lt;Node&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    stack.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        Node node=stack.pop();</span><br><span class="line">        res.add(node.val);</span><br><span class="line">        List&lt;Node&gt; children=node.children;</span><br><span class="line">        <span class="comment">//逆序添加</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=children.size()-<span class="number">1</span>;i&gt;=<span class="number">0</span>;i--) &#123;</span><br><span class="line">            stack.add(children.get(i));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>到这里我是真的对遍历的那个板子无感了，这里我开始想用板子写，结果发现并不好写，无从下手（可能是我太菜），所以采用了经典的前序遍历方式，果然经典就是经典，通用性很强，而且相当好理解，所以以后遇到遍历的题目，尽量还是自己写，别套板子（对后序的板子也一直不是特别理解，所以也一直没记住，套板子还是要建立在理解的基础上啊，不然永远不会做！）</p>
<h2 id="94-二叉树的中序遍历"><a href="#94-二叉树的中序遍历" class="headerlink" title="94. 二叉树的中序遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-inorder-traversal/" >94. 二叉树的中序遍历<i class="fas fa-external-link-alt"></i></a></h2><p>Given a binary tree, return the <em>inorder</em> traversal of its nodes’ values.</p>
<p><strong>Example:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">   <span class="number">1</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">2</span></span><br><span class="line">    /</span><br><span class="line">   <span class="number">3</span></span><br><span class="line"></span><br><span class="line">Output: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>]</span><br></pre></td></tr></table></figure>

<p><strong>Follow up:</strong> Recursive solution is trivial, could you do it iteratively?</p>
<p><strong>解法一</strong></p>
<p>递归的方式和模拟栈的方式就不记录了，重点看一下这个板子</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//经典的非递归实现方式</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">inorderTraversal3</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">while</span>(cur!=<span class="keyword">null</span>||!stack.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">while</span> (cur!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            stack.push(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//没有左子树了</span></span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        <span class="comment">//将当前节点添加到res中</span></span><br><span class="line">        res.add(cur.val);</span><br><span class="line">        <span class="comment">//切换为右子树</span></span><br><span class="line">        cur=cur.right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="145-二叉树的后序遍历"><a href="#145-二叉树的后序遍历" class="headerlink" title="145. 二叉树的后序遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-postorder-traversal/" >145. 二叉树的后序遍历<i class="fas fa-external-link-alt"></i></a></h2><p>Given a binary tree, return the <em>postorder</em> traversal of its nodes’ values.</p>
<p><strong>Example:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">   <span class="number">1</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">2</span></span><br><span class="line">    /</span><br><span class="line">   <span class="number">3</span></span><br><span class="line"></span><br><span class="line">Output: [<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>]</span><br></pre></td></tr></table></figure>

<p><strong>Follow up:</strong> Recursive solution is trivial, could you do it iteratively?</p>
<p><strong>解法一</strong></p>
<p>这题是个hard题，没那么容易（不过根据bobo老师的方式来做确实简单😂）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">postorderTraversal3</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root,lastNode=<span class="keyword">null</span>; <span class="comment">//lastNode为上一次访问的节点</span></span><br><span class="line">    <span class="keyword">while</span>(cur!=<span class="keyword">null</span>||!stack.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">while</span> (cur!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            stack.push(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//没有左子树了,把后一个左节点拿出来</span></span><br><span class="line">        cur=stack.peek();</span><br><span class="line">        <span class="comment">//如果没有右节点,或者右节点访问过了</span></span><br><span class="line">        <span class="keyword">if</span> (cur.right==<span class="keyword">null</span>||cur.right==lastNode) &#123;</span><br><span class="line">            <span class="comment">//添加节点</span></span><br><span class="line">            res.add(cur.val);</span><br><span class="line">            <span class="comment">//记录当前节点为lastNode</span></span><br><span class="line">            lastNode=cur;</span><br><span class="line">            <span class="comment">//将他pop出去</span></span><br><span class="line">            stack.pop();</span><br><span class="line">            <span class="comment">//节点已经弹出</span></span><br><span class="line">            <span class="comment">//指向null,不然就死循环了</span></span><br><span class="line">            cur=<span class="keyword">null</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//右节点不为空,并且没访问过</span></span><br><span class="line">            <span class="comment">//切换为右子树,重复上面的步骤</span></span><br><span class="line">            cur=cur.right;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这种题一定要记住 “招式”，乱写只会越写越乱</p>
<p><strong>解法二</strong></p>
<p>这种解法似乎更加容易理解！！！</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">postorderTraversals</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    stack.push(root);</span><br><span class="line">    TreeNode lastNode=<span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        TreeNode cur=stack.peek();</span><br><span class="line">        <span class="keyword">if</span> ((cur.left==<span class="keyword">null</span> &amp;&amp; cur.right ==<span class="keyword">null</span>) || (lastNode!=<span class="keyword">null</span> &amp;&amp;( cur.left==lastNode || cur.right==lastNode))) &#123;</span><br><span class="line">            stack.pop();</span><br><span class="line">            res.add(cur.val);</span><br><span class="line">            lastNode=cur;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">if</span> (cur.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                stack.push(cur.right);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (cur.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                stack.push(cur.left);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="590-N叉树的后序遍历"><a href="#590-N叉树的后序遍历" class="headerlink" title="590. N叉树的后序遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/" >590. N叉树的后序遍历<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个 N 叉树，返回其节点值的<em>后序遍历</em>。</p>
<p>例如，给定一个 <code>3叉树</code> :</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2019/12/01/KAQP9UNfV5bau7J.png"
                      alt="NTree"
                ></p>
<p>返回其后序遍历: <code>[5,6,3,2,4,1]</code>.</p>
<p><strong>说明:</strong> 递归法很简单，你可以使用迭代法完成此题吗?</p>
<p><strong>解法一</strong></p>
<p>递归的解法，没啥好说的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">List&lt;Integer&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">postorder</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    List&lt;Node&gt; children=root.children;</span><br><span class="line">    <span class="keyword">for</span> (Node node:children) &#123;</span><br><span class="line">        dfs(node);</span><br><span class="line">    &#125;</span><br><span class="line">    res.add(root.val);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>锁了！这才是树遍历的板子</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">postorder</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    Stack&lt;Node&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    stack.push(root);</span><br><span class="line">    Node lastNode=<span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        Node node=stack.peek();</span><br><span class="line">        List&lt;Node&gt; children=node.children;</span><br><span class="line">        <span class="keyword">if</span> (children.isEmpty() || (lastNode!=<span class="keyword">null</span> &amp;&amp; lastNode == children.get(children.size()-<span class="number">1</span>))) &#123;</span><br><span class="line">            res.add(node.val);</span><br><span class="line">            stack.pop();</span><br><span class="line">            lastNode=node;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">int</span> i=children.size()-<span class="number">1</span>;i&gt;=<span class="number">0</span>;i--) &#123;</span><br><span class="line">                stack.push(children.get(i));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这题开始因为一个空的case把我搞晕了，搞了半天才发现</p>
<h2 id="102-二叉树的层次遍历"><a href="#102-二叉树的层次遍历" class="headerlink" title="102. 二叉树的层次遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-level-order-traversal/" >102. 二叉树的层次遍历<i class="fas fa-external-link-alt"></i></a></h2><p>Given a binary tree, return the <em>level order</em> traversal of its nodes’ values. (ie, from left to right, level by level).</p>
<p>For example:<br>Given binary tree <code>[3,9,20,null,null,15,7]</code>,</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>

<p>return its level order traversal as:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">  [<span class="number">3</span>],</span><br><span class="line">  [<span class="number">9</span>,<span class="number">20</span>],</span><br><span class="line">  [<span class="number">15</span>,<span class="number">7</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>BFS，利用队列</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; levelOrder(TreeNode root) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>)<span class="keyword">return</span> res;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="comment">//count代表的其实就是每一层的节点个数</span></span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        List&lt;Integer&gt; list=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            <span class="comment">//取出当前节点,并将其左右子节点入队列</span></span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            list.add(node.val);</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        res.add(list);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>递归DFS，这种其实还是挺有意思的，可以看下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; levelOrder(TreeNode root) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    helper(res, root, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">helper</span><span class="params">(List&lt;List&lt;Integer&gt;&gt; res, TreeNode root, <span class="keyword">int</span> depth)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">    <span class="comment">//需要增加一层</span></span><br><span class="line">    <span class="keyword">if</span> (res.size() == depth) res.add(<span class="keyword">new</span> LinkedList&lt;&gt;());</span><br><span class="line">    res.get(depth).add(root.val);</span><br><span class="line">    helper(res, root.left, depth + <span class="number">1</span>);</span><br><span class="line">    helper(res, root.right, depth + <span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="429-N叉树的层序遍历"><a href="#429-N叉树的层序遍历" class="headerlink" title="429. N叉树的层序遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/" >429. N叉树的层序遍历<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个 N 叉树，返回其节点值的<em>层序遍历</em>。 (即从左到右，逐层遍历)。</p>
<p>例如，给定一个 <code>3叉树</code> :</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2019/12/01/He8KVlms1jynbvr.png"
                      alt="NTee"
                ></p>
<p>返回其层序遍历:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">     [<span class="number">1</span>],</span><br><span class="line">     [<span class="number">3</span>,<span class="number">2</span>,<span class="number">4</span>],</span><br><span class="line">     [<span class="number">5</span>,<span class="number">6</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<ol>
<li>树的深度不会超过 <code>1000</code>。</li>
<li>树的节点总数不会超过 <code>5000</code>。</li>
</ol>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; levelOrder(Node root) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    Queue&lt;Node&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        List&lt;Integer&gt; temp=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            Node node=queue.poll();</span><br><span class="line">            temp.add(node.val);</span><br><span class="line">            <span class="keyword">for</span> (Node child:node.children) &#123;</span><br><span class="line">                queue.add(child);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (!temp.isEmpty()) &#123;</span><br><span class="line">            res.add(temp);   </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="107-二叉树的层次遍历-II"><a href="#107-二叉树的层次遍历-II" class="headerlink" title="107. 二叉树的层次遍历 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/" >107. 二叉树的层次遍历 II<i class="fas fa-external-link-alt"></i></a></h2><p>Given a binary tree, return the <em>bottom-up level order</em> traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root).</p>
<p>For example:<br>Given binary tree <code>[3,9,20,null,null,15,7]</code>,</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>



<p>return its bottom-up level order traversal as:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">  [<span class="number">15</span>,<span class="number">7</span>],</span><br><span class="line">  [<span class="number">9</span>,<span class="number">20</span>],</span><br><span class="line">  [<span class="number">3</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; levelOrderBottom(TreeNode root) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)<span class="keyword">return</span> res;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        List&lt;Integer&gt; list=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode top=queue.poll();</span><br><span class="line">            <span class="keyword">if</span> (top.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(top.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (top.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(top.right);</span><br><span class="line">            &#125;</span><br><span class="line">            list.add(top.val);</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//从头添加</span></span><br><span class="line">        res.add(<span class="number">0</span>,list);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>主要是复习下层次遍历，相比上面就多了 <code>res.add(0,list)</code> 从头部添加</p>
<h2 id="103-二叉树的锯齿形层次遍历"><a href="#103-二叉树的锯齿形层次遍历" class="headerlink" title="103. 二叉树的锯齿形层次遍历"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/" >103. 二叉树的锯齿形层次遍历<i class="fas fa-external-link-alt"></i></a></h2><p>Given a binary tree, return the <em>zigzag level order</em> traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).</p>
<p>For example:<br>Given binary tree <code>[3,9,20,null,null,15,7]</code>,</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>

<p>return its zigzag level order traversal as:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">  [<span class="number">3</span>],</span><br><span class="line">  [<span class="number">20</span>,<span class="number">9</span>],</span><br><span class="line">  [<span class="number">15</span>,<span class="number">7</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; zigzagLevelOrder(TreeNode root) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)<span class="keyword">return</span> res;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">boolean</span> reverse=<span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        LinkedList&lt;Integer&gt; list=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            <span class="keyword">if</span> (reverse) &#123;</span><br><span class="line">                <span class="comment">//从头添加，相当于逆序了</span></span><br><span class="line">                list.addFirst(node.val);</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                list.add(node.val);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        reverse=!reverse;</span><br><span class="line">        res.add(list);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>和上面一题一样，老想着怎么去按照题目的要求去遍历节点，哎，太蠢了，灵活一点啊</p>
<h2 id="199-二叉树的右视图"><a href="#199-二叉树的右视图" class="headerlink" title="199. 二叉树的右视图"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-right-side-view/" >199. 二叉树的右视图<i class="fas fa-external-link-alt"></i></a></h2><p>给定一棵二叉树，想象自己站在它的右侧，按照从顶部到底部的顺序，返回从右侧所能看到的节点值。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">5</span>,<span class="keyword">null</span>,<span class="number">4</span>]</span><br><span class="line">输出: [<span class="number">1</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line">解释:</span><br><span class="line"></span><br><span class="line">   <span class="number">1</span>            &lt;---</span><br><span class="line"> /   \</span><br><span class="line"><span class="number">2</span>     <span class="number">3</span>         &lt;---</span><br><span class="line"> \     \</span><br><span class="line">  <span class="number">5</span>     <span class="number">4</span>       &lt;---</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>还是和上面一样，一上午做了三道一样的题，这题吸取了上面的教训没有去想怎么遍历了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">rightSideView</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    LinkedList&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//取每一层最后一个节点</span></span><br><span class="line">            <span class="keyword">if</span> (count==<span class="number">1</span>) &#123;</span><br><span class="line">                res.add(node.val);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>  res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>只记录每一层最后一个节点，最后得到的就是右视图</p>
<p><strong>解法二</strong></p>
<p>dfs，其实就是一直向右走，走不动就向左走，这样遍历的轨迹就是沿着二叉树的右边缘向下的，我们只需要记录层数，然后当层数和res数量相等的时候记录结果就行了（看见头条面试要求写logN空间的，应该就是这种解法了，但是下面的解法空间复杂度应该还是O(N)的，最坏情况下形成一链表就成N了，不过相比上面层次遍历永远是N的做法还是要好一点）</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">rightSideView</span><span class="params">(root *TreeNode)</span> []<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode, depth <span class="keyword">int</span>)</span></span></span><br><span class="line">    <span class="keyword">var</span> res = <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="number">0</span>)</span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode, depth <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> depth &gt; <span class="built_in">len</span>(res) &#123;</span><br><span class="line">            res = <span class="built_in">append</span>(res, root.Val)</span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Right, depth+<span class="number">1</span>)</span><br><span class="line">        dfs(root.Left, depth+<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root, <span class="number">1</span>)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="637-二叉树的层平均值"><a href="#637-二叉树的层平均值" class="headerlink" title="637. 二叉树的层平均值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/" >637. 二叉树的层平均值<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个非空二叉树, 返回一个由每层节点平均值组成的数组.</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">    <span class="number">3</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">9</span>  <span class="number">20</span></span><br><span class="line">    /  \</span><br><span class="line">   <span class="number">15</span>   <span class="number">7</span></span><br><span class="line">输出: [<span class="number">3</span>, <span class="number">14.5</span>, <span class="number">11</span>]</span><br><span class="line">解释:</span><br><span class="line">第<span class="number">0</span>层的平均值是 <span class="number">3</span>,  第<span class="number">1</span>层是 <span class="number">14.5</span>, 第<span class="number">2</span>层是 <span class="number">11.</span> 因此返回 [<span class="number">3</span>, <span class="number">14.5</span>, <span class="number">11</span>].</span><br></pre></td></tr></table></figure>


<p><strong>注意：</strong></p>
<ol>
<li>节点值的范围在32位有符号整数范围内。</li>
</ol>
<p><strong>解法一</strong></p>
<p>一百遍啊一百遍，这应该属于树类型题的HelloWorld吧 ~ </p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Double&gt; <span class="title">averageOfLevels</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    &#125;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    List&lt;Double&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span> (!queue.isEmpty()) &#123;</span><br><span class="line">        <span class="keyword">int</span> size=queue.size();</span><br><span class="line">        <span class="keyword">int</span> temp=size;</span><br><span class="line">        <span class="keyword">double</span> average=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(size--&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode cur=queue.poll();</span><br><span class="line">            average+=cur.val;</span><br><span class="line">            <span class="keyword">if</span> (cur.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(cur.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (cur.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(cur.right);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        average/=temp;</span><br><span class="line">        res.add(average);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="104-二叉树的最大深度"><a href="#104-二叉树的最大深度" class="headerlink" title="104. 二叉树的最大深度"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/" >104. 二叉树的最大深度<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，找出其最大深度。</p>
<p>二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。</p>
<p><strong>说明:</strong> 叶子节点是指没有子节点的节点。</p>
<p><strong>示例：</strong><br>给定二叉树 [3,9,20,null,null,15,7]</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>


<p>返回它的最大深度 3 。</p>
<p><strong>解法一</strong></p>
<p>递归解法，很简洁</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//maxDepth(root)=1+max(maxDepth(root.left),maxDepth(root.right));</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxDepth</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> maxLeft=maxDepth(root.left);</span><br><span class="line">    <span class="keyword">int</span> maxRight=maxDepth(root.right);</span><br><span class="line">    <span class="keyword">return</span> (maxLeft&gt;maxRight?maxLeft:maxRight)+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>BFS，广度优先搜索</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxDepth</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">0</span>;<span class="comment">//注意初始值</span></span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        max++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="559-N叉树的最大深度"><a href="#559-N叉树的最大深度" class="headerlink" title="559. N叉树的最大深度"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-depth-of-n-ary-tree/" >559. N叉树的最大深度<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个 N 叉树，找到其最大深度。</p>
<p>最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。</p>
<p>例如，给定一个 <code>3叉树</code> :</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s2.ax1x.com/2019/11/20/MWwEt0.png"
                      alt="3叉树"
                ></p>
<p>我们应返回其最大深度，3。</p>
<p><strong>说明:</strong></p>
<ol>
<li>树的深度不会超过 <code>1000</code>。</li>
<li>树的节点总不会超过 <code>5000</code>。</li>
</ol>
<p><strong>解法一</strong></p>
<p>没啥好说的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxDepth</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line">    List&lt;Node&gt; children=root.children;</span><br><span class="line">    <span class="keyword">for</span> (Node node:children) &#123;</span><br><span class="line">        max=Math.max(max,maxDepth(node));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="111-二叉树的最小深度"><a href="#111-二叉树的最小深度" class="headerlink" title="111. 二叉树的最小深度"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/" >111. 二叉树的最小深度<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，找出其最小深度。</p>
<p>最小深度是从根节点到最近叶子节点的最短路径上的节点数量。</p>
<p><strong>说明:</strong> 叶子节点是指没有子节点的节点。</p>
<p><strong>示例:</strong></p>
<p>给定二叉树 <code>[3,9,20,null,null,15,7]</code>   </p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>


<p>返回它的最小深度  2.</p>
<p><strong>解法一</strong></p>
<p>最大都求了，最小也来一发，经典BFS做法，求最短路径</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minDepth</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">int</span> min=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        min++;</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            <span class="keyword">if</span> (node.left==<span class="keyword">null</span> &amp;&amp; node.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">                <span class="keyword">return</span> min;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> min;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>递归</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minDepth</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> minDepth(root.right)+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> minDepth(root.left)+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Math.min(minDepth(root.left),minDepth(root.right))+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>很上面最大的相反，但是有个细节需要注意，如果一个根节点左右子树，<strong>有一颗为空</strong>，如果不处理，按照之前的逻辑，这颗空子树下一次就会返回0，肯定会比另一颗小最后返回的就是到这颗子树的路径，但是仔细想想这样是正确的么？明显不是，最短路径的尽头一定是叶子节点也就是左右子树都为空的时候，所以这里需要特别注意</p>
<h2 id="226-翻转二叉树"><a href="#226-翻转二叉树" class="headerlink" title="226. 翻转二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/invert-binary-tree/" >226. 翻转二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>翻转一棵二叉树。</p>
<p><strong>示例：</strong></p>
<p>输入：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">     <span class="number">4</span></span><br><span class="line">   /   \</span><br><span class="line">  <span class="number">2</span>     <span class="number">7</span></span><br><span class="line"> / \   / \</span><br><span class="line"><span class="number">1</span>   <span class="number">3</span> <span class="number">6</span>   <span class="number">9</span></span><br></pre></td></tr></table></figure>


<p>输出：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">     <span class="number">4</span></span><br><span class="line">   /   \</span><br><span class="line">  <span class="number">7</span>     <span class="number">2</span></span><br><span class="line"> / \   / \</span><br><span class="line"><span class="number">9</span>   <span class="number">6</span> <span class="number">3</span>   <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>备注:</strong><br>这个问题是受到 Max Howell 的 原问题 启发的 ：</p>
<blockquote>
<p>谷歌：我们90％的工程师使用您编写的软件(Homebrew)，但是您却无法在面试时在白板上写出翻转二叉树这道题，这太糟糕了。</p>
</blockquote>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">invertTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    invertTree(root.left);</span><br><span class="line">    invertTree(root.right);</span><br><span class="line">    <span class="comment">//交换左右节点</span></span><br><span class="line">    TreeNode temp=root.left;</span><br><span class="line">    root.left=root.right;</span><br><span class="line">    root.right=temp;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意递归调用和交换节点的顺序，不能搞反了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">invertTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode right=root.right;</span><br><span class="line">    root.right=invertTree(root.left);</span><br><span class="line">    root.left=invertTree(right);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>比较简洁也比较符合递归的做法</p>
<h2 id="100-相同的树"><a href="#100-相同的树" class="headerlink" title="100. 相同的树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/same-tree/" >100. 相同的树<i class="fas fa-external-link-alt"></i></a></h2><p>给定两个二叉树，编写一个函数来检验它们是否相同。</p>
<p>如果两个树在结构上相同，并且节点具有相同的值，则认为它们是相同的。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:       <span class="number">1</span>         <span class="number">1</span></span><br><span class="line">          / \       / \</span><br><span class="line">         <span class="number">2</span>   <span class="number">3</span>     <span class="number">2</span>   <span class="number">3</span></span><br><span class="line"></span><br><span class="line">        [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],   [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line"></span><br><span class="line">输出: <span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:      <span class="number">1</span>          <span class="number">1</span></span><br><span class="line">          /           \</span><br><span class="line">         <span class="number">2</span>             <span class="number">2</span></span><br><span class="line">    </span><br><span class="line">        [<span class="number">1</span>,<span class="number">2</span>],     [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">输出: <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:       <span class="number">1</span>         <span class="number">1</span></span><br><span class="line">          / \       / \</span><br><span class="line">         <span class="number">2</span>   <span class="number">1</span>     <span class="number">1</span>   <span class="number">2</span></span><br><span class="line">        </span><br><span class="line">        [<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>],   [<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line">输出: <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSameTree</span><span class="params">(TreeNode p, TreeNode q)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (p==<span class="keyword">null</span> &amp;&amp; q==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (p!=<span class="keyword">null</span> &amp;&amp; q!=<span class="keyword">null</span> &amp;&amp; p.val==q.val) &#123;</span><br><span class="line">        <span class="keyword">return</span> isSameTree(p.right,q.right)&amp;&amp;isSameTree(p.left,q.left);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="951-翻转等价二叉树"><a href="#951-翻转等价二叉树" class="headerlink" title="951. 翻转等价二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/flip-equivalent-binary-trees/" >951. 翻转等价二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>我们可以为二叉树 T 定义一个翻转操作，如下所示：选择任意节点，然后交换它的左子树和右子树。</p>
<p>只要经过一定次数的翻转操作后，能使 X 等于 Y，我们就称二叉树 X _翻转等价_于二叉树 Y。</p>
<p>编写一个判断两个二叉树是否是_翻转等价_的函数。这些树由根节点 <code>root1</code> 和 <code>root2</code> 给出。</p>
<p><strong>示例：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：root1 = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,null,null,null,<span class="number">7</span>,<span class="number">8</span>], root2 = [<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,null,<span class="number">6</span>,<span class="number">4</span>,<span class="number">5</span>,null,null,null,null,<span class="number">8</span>,<span class="number">7</span>]</span><br><span class="line">输出：<span class="literal">true</span></span><br><span class="line">解释：我们翻转值为 <span class="number">1</span>，<span class="number">3</span> 以及 <span class="number">5</span> 的三个节点。</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li> 每棵树最多有 <code>100</code> 个节点。</li>
<li> 每棵树中的每个值都是唯一的、在 <code>[0, 99]</code> 范围内的整数。</li>
</ol>
<p><strong>解法一</strong></p>
<p>交错的比较就行了</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * type TreeNode struct &#123;</span></span><br><span class="line"><span class="comment"> *     Val int</span></span><br><span class="line"><span class="comment"> *     Left *TreeNode</span></span><br><span class="line"><span class="comment"> *     Right *TreeNode</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">flipEquiv</span><span class="params">(root1 *TreeNode, root2 *TreeNode)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root1 == <span class="literal">nil</span> &amp;&amp; root2 == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> root1 == <span class="literal">nil</span> || root2 == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> root1.Val != root2.Val &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (flipEquiv(root1.Left, root2.Left) &amp;&amp; </span><br><span class="line">            flipEquiv(root1.Right, root2.Right)) || </span><br><span class="line">           (flipEquiv(root1.Left, root2.Right) &amp;&amp;</span><br><span class="line">            flipEquiv(root1.Right, root2.Left))</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="572-另一个树的子树"><a href="#572-另一个树的子树" class="headerlink" title="572. 另一个树的子树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/subtree-of-another-tree/" >572. 另一个树的子树<i class="fas fa-external-link-alt"></i></a></h2><p>给定两个非空二叉树 s 和 t，检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。</p>
<p><strong>示例 1:</strong><br>给定的树 s:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">3</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">4</span>   <span class="number">5</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">2</span></span><br></pre></td></tr></table></figure>


<p>给定的树 t：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">4</span> </span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p>返回 <strong>true</strong>，因为 t 与 s 的一个子树拥有相同的结构和节点值。</p>
<p><strong>示例 2:</strong><br>给定的树 s：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">3</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">4</span>   <span class="number">5</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">2</span></span><br><span class="line">   /</span><br><span class="line">  <span class="number">0</span></span><br></pre></td></tr></table></figure>

<p>给定的树 t：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">4</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p>返回 <strong>false</strong></p>
<p><strong>解法一</strong></p>
<p>先上一个错误解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSubtree</span><span class="params">(TreeNode s, TreeNode t)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (t==<span class="keyword">null</span> &amp;&amp; s==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (s!=<span class="keyword">null</span>&amp;&amp; t!=<span class="keyword">null</span> &amp;&amp; s.val == t.val) &#123;</span><br><span class="line">        <span class="keyword">return</span> isSubtree(s.left,t.left) &amp;&amp; isSubtree(s.right,t.right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> isSubtree(s.left,t) | isSubtree(s.right,t);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>过了146/176的case，但是这个明显是错的，不过核心的递归还是大概雏形写出来了</p>
<p><strong>解法二</strong></p>
<p>思考了一会，光速瞄了一眼评论区，隐约看到了有人说双递归，然后想到了下面的解</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//简化代码</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSubtree</span><span class="params">(TreeNode s, TreeNode t)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> isSame(s,t)| isSubtree(s.left,t) | isSubtree(s.right,t);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSame</span><span class="params">(TreeNode s, TreeNode t)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span> &amp;&amp; t==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;        </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (s==<span class="keyword">null</span> || t==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> s.val==t.val &amp;&amp; isSame(s.left,t.left) &amp;&amp; isSame(s.right,t.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>开始的代码没这么简洁，比较罗嗦，要判断一棵树是不是另一颗的子树很好判断，要么s和t直接相等，要么t是s左子树的子树，或者右子树的子树，所以我们还需要一个函数判断两个两棵树是否相等，只用一个函数确实不好实现</p>
<p><strong>解法三</strong></p>
<p>其实还有一种解法，也是最开始想到的，就是直接中序遍历和前序遍历，得到两个序列，然后用kmp匹配两棵树，kmp很久没看了，不会写了，后面有时间再来写</p>
<h2 id="面试题26-树的子结构"><a href="#面试题26-树的子结构" class="headerlink" title="面试题26. 树的子结构"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/" >面试题26. 树的子结构<i class="fas fa-external-link-alt"></i></a></h2><p>输入两棵二叉树A和B，判断B是不是A的子结构。(约定空树不是任意一个树的子结构)</p>
<p>B是A的子结构， 即 A中有出现和B相同的结构和节点值。</p>
<p><strong>例如:</strong><br>给定的树 A:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">3</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">4</span>   <span class="number">5</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p>给定的树 B：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">4</span> </span><br><span class="line"> /</span><br><span class="line"><span class="number">1</span></span><br></pre></td></tr></table></figure>


<p>返回 true，因为 B 与 A 的一个子树拥有相同的结构和节点值。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：A = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>], B = [<span class="number">3</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：A = [<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">2</span>], B = [<span class="number">4</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>限制：</strong></p>
<p>0 &lt;= 节点个数 &lt;= 10000</p>
<p><strong>解法一</strong></p>
<p>一样的题为啥还加上？仔细看题，我开始也以为是一样的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSubStructure</span><span class="params">(TreeNode A, TreeNode B)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(A==<span class="keyword">null</span> || B==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> isSame(A,B) | isSubStructure(A.left,B) | isSubStructure(A.right,B);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSame</span><span class="params">(TreeNode A,TreeNode B)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (B==<span class="keyword">null</span>) &#123; <span class="comment">//AB同时为NULL应该返回true,所以上下不能交换</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(A==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> A.val==B.val &amp;&amp; isSame(A.left,B.left) &amp;&amp; isSame(A.right,B.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里说的是子结构不是子树，isSame函数不需要保证完全相等，这里就需要注意了，当<code>A!=null &amp;&amp; B==null</code>的时候就说明B已经匹配完了A还没有，这就说明B是A的子结构</p>
<p><strong>UPDATE(2020.5.7)</strong></p>
<p>换了一下写法，不用考虑顺序了</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">isSubStructure</span><span class="params">(A *TreeNode, B *TreeNode)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> B==<span class="literal">nil</span> || A==<span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(A,B) || isSubStructure(A.Left,B) || isSubStructure(A.Right,B)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(A *TreeNode, B *TreeNode)</span><span class="title">bool</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> A==<span class="literal">nil</span> &amp;&amp; B==<span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> A==<span class="literal">nil</span> || B==<span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> B==<span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> A.Val==B.Val &amp;&amp; dfs(A.Left,B.Left) &amp;&amp; dfs(A.Right,B.Right)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="222-完全二叉树的节点个数"><a href="#222-完全二叉树的节点个数" class="headerlink" title="222. 完全二叉树的节点个数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/count-complete-tree-nodes/" >222. 完全二叉树的节点个数<i class="fas fa-external-link-alt"></i></a></h2><p>给出一个<strong>完全二叉树</strong>，求出该树的节点个数。</p>
<p><strong>说明：</strong></p>
<p>完全二叉树的定义如下：在完全二叉树中，除了最底层节点可能没填满外，其余每层节点数都达到最大值，并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层，则该层包含 1~ 2h 个节点。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">3</span></span><br><span class="line"> / \  /</span><br><span class="line"><span class="number">4</span>  <span class="number">5</span> <span class="number">6</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">6</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>BFS，权当复习了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//BFS</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countNodes</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> nextLevel=queue.size();</span><br><span class="line">        <span class="keyword">while</span>(nextLevel&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll(); </span><br><span class="line">            count++;</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            nextLevel--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>递归解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//暴力</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countNodes</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">return</span> countNodes(root.left)+countNodes(root.right)+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>更加精简点可以缩减成一行</p>
<p><strong>解法三</strong></p>
<p>这题是mid难度，而且题目给的条件还没用上：<strong>这是一颗完全二叉树</strong>，所以我们可以利用它的性质来做，众所周知，<strong>满二叉树的节点个数</strong>可以直接根据公式 <code>2^H-1</code> 计算得来，所以我们只要判断当前的完全二叉树是不是<strong>满二叉树</strong>，如果是直接算出来，这样就可以省去中间很多节点的遍历</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//利用完全二叉树的性质</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countNodes</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    TreeNode left=root.left;</span><br><span class="line">    TreeNode right=root.right;</span><br><span class="line">    <span class="keyword">int</span> hight=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left!=<span class="keyword">null</span> &amp;&amp; right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        left=left.left;</span><br><span class="line">        right=right.right;</span><br><span class="line">        hight++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//同时向左向右走，走到最后left==null就说明这颗树是满二叉树，可以利用公式直接求出节点个数</span></span><br><span class="line">    <span class="comment">//否则就对其左右子树递归求解</span></span><br><span class="line">    <span class="keyword">return</span> left==<span class="keyword">null</span>?(<span class="number">1</span>&lt;&lt;hight)-<span class="number">1</span>:countNodes(root.left)+countNodes(root.right)+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>不得不说这样的方式还是挺巧妙的，时间复杂度应该是<code>O(2logN)</code>? </p>
<h2 id="112-路径总和"><a href="#112-路径总和" class="headerlink" title="112. 路径总和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/path-sum/" >112. 路径总和<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树和一个目标和，判断该树中是否存在<strong>根节点到叶子节点</strong>的路径，这条路径上所有节点值相加等于目标和。</p>
<p><strong>说明:</strong> 叶子节点是指没有子节点的节点。</p>
<p><strong>示例:</strong><br>给定如下二叉树，以及目标和 <code>sum = 22</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">      <span class="number">5</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">4</span>   <span class="number">8</span></span><br><span class="line">   /   / \</span><br><span class="line">  <span class="number">11</span>  <span class="number">13</span>  <span class="number">4</span></span><br><span class="line"> /  \      \</span><br><span class="line"><span class="number">7</span>    <span class="number">2</span>      <span class="number">1</span></span><br></pre></td></tr></table></figure>
<p>返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 <code>5-&gt;4-&gt;11-&gt;2</code></p>
<p><strong>解法一</strong></p>
<p>递归解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">hasPathSum</span><span class="params">(TreeNode root, <span class="keyword">int</span> sum)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//需要注意这里的叶节点判断</span></span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>&amp;&amp;root.val==sum) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> hasPathSum(root.left,sum-root.val) || hasPathSum(root.right,sum-root.val);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>值得注意的地方就是这个叶子节点的判断，一开始没注意到，直接写的 <code>root.val==sum</code> ，其实如果不是叶子节点的话，其实是不成立的，比如</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">1</span></span><br><span class="line"> /</span><br><span class="line"><span class="number">2</span>       sum=<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p>其实这就是<code>false</code> ，因为他没有右子树，而题目要求的是从<strong>根节点到叶子节点</strong></p>
<h2 id="404-左叶子之和"><a href="#404-左叶子之和" class="headerlink" title="404. 左叶子之和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sum-of-left-leaves/" >404. 左叶子之和<i class="fas fa-external-link-alt"></i></a></h2><p>计算给定二叉树的所有左叶子之和。</p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>

<p>在这个二叉树中，有两个左叶子，分别是 9 和 15，所以返回 24</p>
<p><strong>解法一</strong></p>
<p>说实话，这些题给的例子都挺误导人的，会让人不自觉地忽略<strong>叶子节点</strong>这个条件😂</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">sumOfLeftLeaves</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    sumOfLeft(root);</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sumOfLeft</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//注意这里的条件！！！！</span></span><br><span class="line">    <span class="keyword">if</span> (root.left!=<span class="keyword">null</span> &amp;&amp; root.left.left==<span class="keyword">null</span> &amp;&amp;root.left.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        sum+=root.left.val;</span><br><span class="line">    &#125;</span><br><span class="line">    sumOfLeft(root.left);</span><br><span class="line">    sumOfLeft(root.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="257-二叉树的所有路径"><a href="#257-二叉树的所有路径" class="headerlink" title="257. 二叉树的所有路径"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-paths/" >257. 二叉树的所有路径<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，返回所有从根节点到叶子节点的路径。</p>
<p><strong>说明:</strong> 叶子节点是指没有子节点的节点。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"> 输入:</span><br><span class="line"></span><br><span class="line">   <span class="number">1</span></span><br><span class="line"> /   \</span><br><span class="line"><span class="number">2</span>     <span class="number">3</span></span><br><span class="line"> \</span><br><span class="line">  <span class="number">5</span></span><br><span class="line"></span><br><span class="line">输出: [<span class="string">&quot;1-&gt;2-&gt;5&quot;</span>, <span class="string">&quot;1-&gt;3&quot;</span>]</span><br><span class="line"></span><br><span class="line">解释: 所有根节点到叶子节点的路径为: <span class="number">1</span>-&gt;<span class="number">2</span>-&gt;<span class="number">5</span>, <span class="number">1</span>-&gt;<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>递归DFS的解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//DFS</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">binaryTreePaths</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;String&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (root!=<span class="keyword">null</span>&amp;&amp;root.left==<span class="keyword">null</span>&amp;&amp;root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        res.add(String.valueOf(root.val));</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//左子树的所有路径</span></span><br><span class="line">    List&lt;String&gt; lefts=binaryTreePaths(root.left);</span><br><span class="line">    <span class="comment">//右子树的所有路径</span></span><br><span class="line">    List&lt;String&gt; rights=binaryTreePaths(root.right);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//在每条路径前面加上当前根节点</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;lefts.size();i++) &#123;</span><br><span class="line">        res.add(root.val+<span class="string">&quot;-&gt;&quot;</span>+lefts.get(i));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;rights.size();i++) &#123;</span><br><span class="line">        res.add(root.val+<span class="string">&quot;-&gt;&quot;</span>+rights.get(i));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>比上面的递归稍微复杂点，核心思想还是要抓住递归的本质，不要去纠结递归每一步都是怎么得到的，从宏观上去写代码，还是要多练啊</p>
<p><strong>解法二</strong></p>
<p>BFS广搜</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">binaryTreePaths</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;String&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; node_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    Stack&lt;String&gt; path_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    node_stack.add(root);</span><br><span class="line">    path_stack.add(String.valueOf(root.val));</span><br><span class="line">    String path=<span class="string">&quot;&quot;</span>;</span><br><span class="line">    <span class="keyword">while</span>(!node_stack.isEmpty())&#123;</span><br><span class="line">        TreeNode node=node_stack.pop();</span><br><span class="line">        path=path_stack.pop();</span><br><span class="line">        <span class="comment">//叶子节点，这条路径搜索结束，添加到res中</span></span><br><span class="line">        <span class="keyword">if</span> (node.left==<span class="keyword">null</span>&amp;&amp;node.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">            res.add(path);</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            node_stack.add(node.left);</span><br><span class="line">            path_stack.add(path+<span class="string">&quot;-&gt;&quot;</span>+node.left.val);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            node_stack.add(node.right);</span><br><span class="line">            path_stack.add(path+<span class="string">&quot;-&gt;&quot;</span>+node.right.val);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里和传统的BFS不太一样，是用的栈来遍历的</p>
<p><strong>解法三</strong></p>
<p>这种解法应该会比上面的解法复杂度低一点</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">binaryTreePaths</span><span class="params">(root *TreeNode)</span> []<span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">string</span></span><br><span class="line">    dfs(root,<span class="string">&quot;&quot;</span>,&amp;res)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//注意这个res要传指针</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(root *TreeNode,path <span class="keyword">string</span>,res *[]<span class="keyword">string</span>)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> root==<span class="literal">nil</span> &#123;<span class="keyword">return</span>&#125;</span><br><span class="line">    path+=strconv.Itoa(root.Val)</span><br><span class="line">    <span class="keyword">if</span> root.Left==<span class="literal">nil</span> &amp;&amp; root.Right==<span class="literal">nil</span>&#123;</span><br><span class="line">        *res=<span class="built_in">append</span>(*res,path)</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root.Left,path+<span class="string">&quot;-&gt;&quot;</span>,res)</span><br><span class="line">    dfs(root.Right,path+<span class="string">&quot;-&gt;&quot;</span>,res)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="113-路径总和-II"><a href="#113-路径总和-II" class="headerlink" title="113. 路径总和 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/path-sum-ii/" >113. 路径总和 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树和一个目标和，找到所有从根节点到叶子节点路径总和等于给定目标和的路径。</p>
<p><strong>说明:</strong> 叶子节点是指没有子节点的节点</p>
<p><strong>示例:</strong><br>给定如下二叉树，以及目标和 <code>sum = 22</code>，</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">      <span class="number">5</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">4</span>   <span class="number">8</span></span><br><span class="line">   /   / \</span><br><span class="line">  <span class="number">11</span>  <span class="number">13</span>  <span class="number">4</span></span><br><span class="line"> /  \    / \</span><br><span class="line"><span class="number">7</span>    <span class="number">2</span>  <span class="number">5</span>   <span class="number">1</span></span><br></pre></td></tr></table></figure>
<p>返回:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">   [<span class="number">5</span>,<span class="number">4</span>,<span class="number">11</span>,<span class="number">2</span>],</span><br><span class="line">   [<span class="number">5</span>,<span class="number">8</span>,<span class="number">4</span>,<span class="number">5</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>和上一题的做法基本一致，本来应该是一遍bugfree的，编译错误整了半天</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; pathSum(TreeNode root, <span class="keyword">int</span> sum) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root!=<span class="keyword">null</span> &amp;&amp; root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span> &amp;&amp; root.val==sum) &#123;</span><br><span class="line">        LinkedList&lt;Integer&gt;  lis= <span class="keyword">new</span> LinkedList&lt;&gt;(); </span><br><span class="line">        lis.add(root.val);</span><br><span class="line">        res.add(lis);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//左右子树符合条件的路径</span></span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; lefts=pathSum(root.left,sum-root.val);</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; rights=pathSum(root.right,sum-root.val);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;lefts.size();i++) &#123;</span><br><span class="line">        ((LinkedList&lt;Integer&gt;)lefts.get(i)).addFirst(root.val);</span><br><span class="line">        res.add(lefts.get(i));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;rights.size();i++) &#123;</span><br><span class="line">        ((LinkedList&lt;Integer&gt;)rights.get(i)).addFirst(root.val);</span><br><span class="line">        res.add(rights.get(i));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>废了老大劲终于把BFS写出来了。。。可以看出还是借鉴的上面的思路</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; pathSum2(TreeNode root,<span class="keyword">int</span> sum) &#123;</span><br><span class="line">    List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> res;</span><br><span class="line">    <span class="comment">//节点栈</span></span><br><span class="line">    Stack&lt;TreeNode&gt; node_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    <span class="comment">//路径栈</span></span><br><span class="line">    Stack&lt;List&lt;Integer&gt;&gt; path_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    <span class="comment">//节点sum栈</span></span><br><span class="line">    Stack&lt;Integer&gt; sum_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    <span class="comment">//给每个栈存入初始值</span></span><br><span class="line">    node_stack.add(root);</span><br><span class="line">    path_stack.add(<span class="keyword">new</span> LinkedList()&#123;&#123;</span><br><span class="line">        add(root.val);</span><br><span class="line">    &#125;&#125;);</span><br><span class="line">    sum_stack.add(root.val);</span><br><span class="line">    <span class="comment">//BFS</span></span><br><span class="line">    <span class="keyword">while</span>(!node_stack.isEmpty())&#123;</span><br><span class="line">        TreeNode node=node_stack.pop();</span><br><span class="line">        List&lt;Integer&gt; pathList=path_stack.pop();</span><br><span class="line">        <span class="keyword">int</span> tempS=sum_stack.pop();</span><br><span class="line">        <span class="comment">//终止条件</span></span><br><span class="line">        <span class="keyword">if</span> (node.left==<span class="keyword">null</span> &amp;&amp; node.right==<span class="keyword">null</span>&amp;&amp;tempS==sum) &#123;</span><br><span class="line">            res.add(pathList);</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">//这三个栈是同步的,node栈存放当前节点</span></span><br><span class="line">            <span class="comment">//path栈存放根节点到当前节点的路径</span></span><br><span class="line">            <span class="comment">//sum栈存放的是path栈中所有节点的val和</span></span><br><span class="line">            node_stack.add(node.left);</span><br><span class="line">            <span class="comment">//这里不要直接操作pathList,否则左右的路径会混在一起</span></span><br><span class="line">            LinkedList&lt;Integer&gt; tlis= <span class="keyword">new</span> LinkedList(pathList);</span><br><span class="line">            tlis.add(node.left.val);</span><br><span class="line">            path_stack.add(tlis);</span><br><span class="line">            <span class="comment">//累加路径上的节点值</span></span><br><span class="line">            sum_stack.add(tempS+node.left.val);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            node_stack.add(node.right);</span><br><span class="line">            <span class="comment">//同上</span></span><br><span class="line">            LinkedList&lt;Integer&gt; tlis= <span class="keyword">new</span> LinkedList(pathList);</span><br><span class="line">            tlis.add(node.right.val);</span><br><span class="line">            path_stack.add(tlis);</span><br><span class="line">            sum_stack.add(tempS+node.right.val);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>用到三个栈，同步保存节点的信息，还是挺简单的</p>
<p><strong>解法三</strong></p>
<p>补一种dfs+回溯的思路，上面的所有路径也可以这样做，感觉会比上面的要好一点</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> List&lt;List&lt;Integer&gt;&gt; pathSum(TreeNode root, <span class="keyword">int</span> sum) &#123;</span><br><span class="line">    dfs(root,sum,<span class="keyword">new</span> ArrayList&lt;&gt;());</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> List&lt;List&lt;Integer&gt;&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode root,<span class="keyword">int</span> sum,List&lt;Integer&gt; lis)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">    lis.add(root.val);</span><br><span class="line">    <span class="keyword">if</span>(root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span> &amp;&amp; sum==root.val)&#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> ArrayList(lis)); <span class="comment">//这里不能return，得到后面回溯后才能return</span></span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        dfs(root.left,sum-root.val,lis);</span><br><span class="line">        dfs(root.right,sum-root.val,lis);</span><br><span class="line">    &#125;</span><br><span class="line">    lis.remove(lis.size()-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="894-所有可能的满二叉树"><a href="#894-所有可能的满二叉树" class="headerlink" title="894. 所有可能的满二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/all-possible-full-binary-trees/" >894. 所有可能的满二叉树<i class="fas fa-external-link-alt"></i></a></h2><p><em>满二叉树</em>是一类二叉树，其中每个结点恰好有 0 或 2 个子结点。</p>
<p>返回包含 <code>N</code> 个结点的所有可能满二叉树的列表。 答案的每个元素都是一个可能树的根结点。</p>
<p>答案中每个树的每个<code>结点</code>都<strong>必须</strong>有 <code>node.val=0</code>。</p>
<p>你可以按任何顺序返回树的最终列表。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/06/13/tXXu4A.png"
                      alt="tXXu4A.png"
                ></p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="number">7</span></span><br><span class="line">输出：[[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">0</span>,<span class="number">0</span>]]</span><br><span class="line">解释：</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= N &lt;= 20</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>这题和上面两题很类似，可惜我并没有直接做出来，菜啊，看了一眼评论区看见了几个for循环立马就懂了，然后过了好几天实现了下，一开始root的位置放错了，改了一会儿</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;TreeNode&gt; <span class="title">allPossibleFBT</span><span class="params">(<span class="keyword">int</span> N)</span> </span>&#123;</span><br><span class="line">    List&lt;TreeNode&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span>(N%<span class="number">2</span>==<span class="number">0</span>) <span class="keyword">return</span> res; <span class="comment">//偶数提前返回，加快速度</span></span><br><span class="line">    <span class="keyword">if</span>(N==<span class="number">1</span>)&#123;</span><br><span class="line">        res.add(<span class="keyword">new</span> TreeNode(<span class="number">0</span>));</span><br><span class="line">        <span class="keyword">return</span> res;  </span><br><span class="line">    &#125;</span><br><span class="line">    N--; <span class="comment">//减去根节点</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;N;i+=<span class="number">2</span>)&#123; <span class="comment">//将左右子树划分位两个奇数</span></span><br><span class="line">        List&lt;TreeNode&gt; lefts=allPossibleFBT(i);</span><br><span class="line">        List&lt;TreeNode&gt; rights=allPossibleFBT(N-i);</span><br><span class="line">        <span class="keyword">for</span>(TreeNode le:lefts)&#123;</span><br><span class="line">            <span class="keyword">for</span>(TreeNode ri:rights)&#123;</span><br><span class="line">                <span class="comment">//一路从最外层移动到这里。。。。</span></span><br><span class="line">                TreeNode root=<span class="keyword">new</span> TreeNode(<span class="number">0</span>); </span><br><span class="line">                root.left=le;</span><br><span class="line">                root.right=ri;</span><br><span class="line">                res.add(root);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="129-求根到叶子节点数字之和"><a href="#129-求根到叶子节点数字之和" class="headerlink" title="129. 求根到叶子节点数字之和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/" >129. 求根到叶子节点数字之和<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，它的每个结点都存放一个 <code>0-9</code> 的数字，每条从根到叶子节点的路径都代表一个数字。</p>
<p>例如，从根到叶子节点路径 <code>1-&gt;2-&gt;3</code> 代表数字 <code>123</code></p>
<p>计算从根到叶子节点生成的所有数字之和。</p>
<p><strong>说明:</strong> 叶子节点是指没有子节点的节点。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">3</span></span><br><span class="line">输出: <span class="number">25</span></span><br><span class="line">解释:</span><br><span class="line">从根到叶子节点路径 <span class="number">1</span>-&gt;<span class="number">2</span> 代表数字 <span class="number">12.</span></span><br><span class="line">从根到叶子节点路径 <span class="number">1</span>-&gt;<span class="number">3</span> 代表数字 <span class="number">13.</span></span><br><span class="line">因此，数字总和 = <span class="number">12</span> + <span class="number">13</span> = <span class="number">25.</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">4</span>,<span class="number">9</span>,<span class="number">0</span>,<span class="number">5</span>,<span class="number">1</span>]</span><br><span class="line">    <span class="number">4</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">9</span>   <span class="number">0</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">5</span>   <span class="number">1</span></span><br><span class="line">输出: <span class="number">1026</span></span><br><span class="line">解释:</span><br><span class="line">从根到叶子节点路径 <span class="number">4</span>-&gt;<span class="number">9</span>-&gt;<span class="number">5</span> 代表数字 <span class="number">495.</span></span><br><span class="line">从根到叶子节点路径 <span class="number">4</span>-&gt;<span class="number">9</span>-&gt;<span class="number">1</span> 代表数字 <span class="number">491.</span></span><br><span class="line">从根到叶子节点路径 <span class="number">4</span>-&gt;<span class="number">0</span> 代表数字 <span class="number">40.</span></span><br><span class="line">因此，数字总和 = <span class="number">495</span> + <span class="number">491</span> + <span class="number">40</span> = <span class="number">1026.</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>BFS，延续上面的做法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">sumNumbers</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span> ) <span class="keyword">return</span> res;</span><br><span class="line">    Stack&lt;TreeNode&gt; node_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    Stack&lt;Integer&gt; sum_stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    node_stack.add(root);</span><br><span class="line">    sum_stack.add(root.val);</span><br><span class="line">    <span class="keyword">while</span>(!node_stack.isEmpty())&#123;</span><br><span class="line">        TreeNode node=node_stack.pop();</span><br><span class="line">        <span class="keyword">int</span> tempS=sum_stack.pop();</span><br><span class="line">        <span class="keyword">if</span> (node.left==<span class="keyword">null</span> &amp;&amp; node.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">            res+=tempS;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            node_stack.add(node.left);</span><br><span class="line">             <span class="comment">//注意*10,在上一层的基础上*10</span></span><br><span class="line">            sum_stack.add(tempS*<span class="number">10</span>+node.left.val);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            node_stack.add(node.right);</span><br><span class="line">            sum_stack.add(tempS*<span class="number">10</span>+node.right.val);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>DFS解法，一开始没想出来。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line"><span class="comment">//DFS</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">sumNumbers2</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    sumNumber(<span class="number">0</span>,root);</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sumNumber</span><span class="params">(<span class="keyword">int</span> parent,TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> cur=parent*<span class="number">10</span>+root.val;</span><br><span class="line">    <span class="comment">//叶子节点</span></span><br><span class="line">    <span class="keyword">if</span> (root!=<span class="keyword">null</span> &amp;&amp; root.left==<span class="keyword">null</span>&amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        sum+=cur;</span><br><span class="line">    &#125;</span><br><span class="line">    sumNumber(cur,root.left);</span><br><span class="line">    sumNumber(cur,root.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1022-从根到叶的二进制数之和"><a href="#1022-从根到叶的二进制数之和" class="headerlink" title="1022. 从根到叶的二进制数之和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sum-of-root-to-leaf-binary-numbers/" >1022. 从根到叶的二进制数之和<i class="fas fa-external-link-alt"></i></a></h2><p>给出一棵二叉树，其上每个结点的值都是 <code>0</code> 或 <code>1</code> 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如，如果路径为 <code>0 -&gt; 1 -&gt; 1 -&gt; 0 -&gt; 1</code>，那么它表示二进制数 <code>01101</code>，也就是 <code>13</code> 。</p>
<p>对树上的每一片叶子，我们都要找出从根到该叶子的路径所表示的数字。</p>
<p>以 <strong>10^9 + 7</strong> 为<strong>模</strong>，返回这些数字之和。</p>
<p><strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/04/28/JI4uDI.png"
                      alt="JI4uDI.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">22</span></span><br><span class="line">解释：(<span class="number">100</span>) + (<span class="number">101</span>) + (<span class="number">110</span>) + (<span class="number">111</span>) = <span class="number">4</span> + <span class="number">5</span> + <span class="number">6</span> + <span class="number">7</span> = <span class="number">22</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li>树中的结点数介于 <code>1</code> 和 <code>1000</code> 之间。</li>
<li>node.val 为 <code>0</code> 或 <code>1</code> 。</li>
</ol>
<p><strong>解法一</strong></p>
<p>和上一题一摸一样，没啥好说的，只不过一个是10进制，一个是二进制</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * type TreeNode struct &#123;</span></span><br><span class="line"><span class="comment"> *     Val int</span></span><br><span class="line"><span class="comment"> *     Left *TreeNode</span></span><br><span class="line"><span class="comment"> *     Right *TreeNode</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> mod=<span class="keyword">int</span>(<span class="number">1e9</span>+<span class="number">7</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">sumRootToLeaf</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    sum:=<span class="number">0</span>;</span><br><span class="line">    dfs(root,<span class="number">0</span>,&amp;sum)</span><br><span class="line">    <span class="keyword">return</span> sum</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(root *TreeNode,cur <span class="keyword">int</span>,sum *<span class="keyword">int</span>)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> root==<span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    cur=(cur&lt;&lt;<span class="number">1</span>+root.Val)%mod</span><br><span class="line">    <span class="keyword">if</span> root!=<span class="literal">nil</span> &amp;&amp; root.Left==<span class="literal">nil</span> &amp;&amp; root.Right==<span class="literal">nil</span>&#123;</span><br><span class="line">        *sum=(*sum+cur)%mod</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root.Left,cur,sum)</span><br><span class="line">    dfs(root.Right,cur,sum)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>这题的数据太弱了，甚至都不用取模照样可以过。。。。我一开始看到1000个节点，还考虑要不要处理大数的情况，看到返回值是int才作罢🤣</p>
</blockquote>
<h2 id="437-路径总和-III"><a href="#437-路径总和-III" class="headerlink" title="437. 路径总和 III"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/path-sum-iii/" >437. 路径总和 III<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，它的每个结点都存放着一个整数值。</p>
<p>找出路径和等于给定数值的路径总数。</p>
<p>路径不需要从根节点开始，也不需要在叶子节点结束，但是路径方向必须是向下的（只能从父节点到子节点）。</p>
<p>二叉树不超过1000个节点，且节点数值范围是 [-1000000,1000000] 的整数。</p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">root = [<span class="number">10</span>,<span class="number">5</span>,-<span class="number">3</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">11</span>,<span class="number">3</span>,-<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">1</span>], sum = <span class="number">8</span></span><br><span class="line">      <span class="number">10</span></span><br><span class="line">     /  \</span><br><span class="line">    <span class="number">5</span>   -<span class="number">3</span></span><br><span class="line">   / \    \</span><br><span class="line">  <span class="number">3</span>   <span class="number">2</span>   <span class="number">11</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">3</span>  -<span class="number">2</span>   <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p>返回 3。和等于 8 的路径有:</p>
<ol>
<li> 5 -&gt; 3</li>
<li> 5 -&gt; 2 -&gt; 1</li>
<li> -3 -&gt; 11</li>
</ol>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">pathSum</span><span class="params">(TreeNode root, <span class="keyword">int</span> sum)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span> ) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=findPath(root,sum);</span><br><span class="line">    res+=pathSum(root.left,sum);</span><br><span class="line">    res+=pathSum(root.right,sum);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findPath</span><span class="params">(TreeNode node,<span class="keyword">int</span> sum)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (node.val==sum) &#123;</span><br><span class="line">        res++;</span><br><span class="line">    &#125;</span><br><span class="line">    res+=findPath(node.left,sum-node.val);</span><br><span class="line">    res+=findPath(node.right,sum-node.val);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><del>emmmm，这题分类是easy确实太迷了，嵌套的递归，看了解法确实看的懂，但是写是绝对写不出来的（眼睛：我懂了，脑子：你懂个锤子）除非能记住</del></p>
<p>回头来看发现其实挺简单的，确实是easy题~ 但是这个解很明显不是最优解，这个里面会有很多的重复的计算，最优解是利用 前缀和+回溯的解法，有点小顶~</p>
<p><strong>解法二</strong></p>
<p>补上前缀和的做法，之前好像是看了答案，然后感觉很难，就没写？今天又重新做了下，先写了暴力解，然后就直接写出了前缀和的做法，感觉前缀和的思路还是挺优秀的，一开始忘了回溯，思考了下意识到这里记录的应该是一条分支之上而下的前缀和，所以在统计完某个节点后应该回溯</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//前缀和的思路O(N)挺不错的</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">pathSum</span><span class="params">(root *TreeNode, sum <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    <span class="comment">//前缀和，记录一条自上而下的路径前缀和</span></span><br><span class="line">    <span class="keyword">var</span> preSum = <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">int</span>)</span><br><span class="line">    preSum[<span class="number">0</span>] = <span class="number">1</span></span><br><span class="line">    dfs(root, <span class="number">0</span>, sum, preSum, &amp;res)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(root *TreeNode, sum <span class="keyword">int</span>, target <span class="keyword">int</span>, preSum <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">int</span>, res *<span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    sum += root.Val</span><br><span class="line">    <span class="comment">//preSum[sum]++，这里WA了一发，写在上面如果tatget为0就把当前节点算进去了</span></span><br><span class="line">    *res += preSum[sum-target]</span><br><span class="line">    preSum[sum]++</span><br><span class="line">    dfs(root.Left, sum, target, preSum, res)</span><br><span class="line">    dfs(root.Right, sum, target, preSum, res)</span><br><span class="line">    preSum[sum]--</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="235-二叉搜索树的最近公共祖先"><a href="#235-二叉搜索树的最近公共祖先" class="headerlink" title="235. 二叉搜索树的最近公共祖先"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/" >235. 二叉搜索树的最近公共祖先<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。</p>
<p>百度百科中最近公共祖先的定义为：对于有根树 T 的两个结点 p、q，最近公共祖先表示为一个结点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（<strong>一个节点也可以是它自己的祖先</strong>）</p>
<p>例如，给定如下二叉搜索树:  <code>root = [6,2,8,0,4,7,9,null,null,3,5]</code></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191001/KlQJmqmdWmP3.png?imageslim"
                      alt="mark"
                ></p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: root = [<span class="number">6</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">0</span>,<span class="number">4</span>,<span class="number">7</span>,<span class="number">9</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="number">5</span>], p = <span class="number">2</span>, q = <span class="number">8</span></span><br><span class="line">输出: <span class="number">6</span> </span><br><span class="line">解释: 节点 <span class="number">2</span> 和节点 <span class="number">8</span> 的最近公共祖先是 <span class="number">6</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: root = [<span class="number">6</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">0</span>,<span class="number">4</span>,<span class="number">7</span>,<span class="number">9</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="number">5</span>], p = <span class="number">2</span>, q = <span class="number">4</span></span><br><span class="line">输出: <span class="number">2</span></span><br><span class="line">解释: 节点 <span class="number">2</span> 和节点 <span class="number">4</span> 的最近公共祖先是 <span class="number">2</span>, 因为根据定义最近公共祖先节点可以为节点本身。</span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<ul>
<li>所有节点的值都是唯一的。</li>
<li>p、q 为不同节点且均存在于给定的二叉搜索树中。</li>
</ul>
<p><strong>解法一</strong></p>
<p>看了一点点思路，然后bugfree</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">lowestCommonAncestor</span><span class="params">(TreeNode root, TreeNode p, TreeNode q)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//特殊情况,其中一个已经是另一个的祖先了</span></span><br><span class="line">    <span class="comment">//if (p==root || q==root) return root;</span></span><br><span class="line">    <span class="comment">//都小于根节点</span></span><br><span class="line">    <span class="keyword">if</span> (p.val&lt;root.val &amp;&amp; q.val&lt;root.val) &#123;</span><br><span class="line">        <span class="keyword">return</span> lowestCommonAncestor(root.left,p,q);</span><br><span class="line">    &#125;<span class="keyword">else</span> <span class="keyword">if</span> (p.val &gt; root.val &amp;&amp; q.val &gt; root.val) &#123;</span><br><span class="line">        <span class="comment">//都大于根节点</span></span><br><span class="line">        <span class="keyword">return</span> lowestCommonAncestor(root.right,p,q);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="comment">//一大一小 或者有一个是root</span></span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其实核心就是利用好BST的性质，左子树一定小于根节点，右子树一定大于根节点，求公共祖先，如果一个节点在左子树，一个在右子树，那么最近的公共祖先一定是root，除此之外，还有一种特殊情况就是当两个节点已经有祖先关系的时候，那么直接返回祖先节点就可以了</p>
<blockquote>
<p>这里其实前面的<code>if</code>可以去掉，题目中说到了所有节点的值都是唯一的，所以节点值相等就说明是同一个节点，就已经包含在最后一个else的情况中了</p>
</blockquote>
<h2 id="98-验证二叉搜索树"><a href="#98-验证二叉搜索树" class="headerlink" title="98. 验证二叉搜索树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/validate-binary-search-tree/" >98. 验证二叉搜索树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，判断其是否是一个有效的二叉搜索树。</p>
<p>假设一个二叉搜索树具有如下特征：</p>
<ul>
<li>节点的左子树只包含<strong>小于</strong>当前节点的数。</li>
<li>节点的右子树只包含<strong>大于</strong>当前节点的数。</li>
<li>所有左子树和右子树自身必须也是二叉搜索树。</li>
</ul>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">    <span class="number">2</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">1</span>   <span class="number">3</span></span><br><span class="line">输出: <span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">1</span>   <span class="number">4</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">3</span>   <span class="number">6</span></span><br><span class="line">输出: <span class="keyword">false</span></span><br><span class="line">解释: 输入为: [<span class="number">5</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="number">6</span>]。</span><br><span class="line">     根节点的值为 <span class="number">5</span> ，但是其右子节点值为 <span class="number">4</span> </span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>递归解法，很巧妙</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValidBST</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> isValidBST(root,<span class="keyword">null</span>,<span class="keyword">null</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValidBST</span><span class="params">(TreeNode node,Integer low,Integer high)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">if</span> (low!=<span class="keyword">null</span> &amp;&amp; low&gt;=node.val || high!=<span class="keyword">null</span> &amp;&amp; high&lt;=node.val) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> isValidBST(node.left,low,node.val) &amp;&amp; isValidBST(node.right,node.val,high);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>一定要注意BST的性质是根节点<strong>大于所有</strong> 右子树的节点，<strong>小于所有</strong>左子树的节点，而不是简单的验证当前节点和左右节点的大小关系就可以了，所以我们在验证的时候传入对应的<strong>上界</strong>和<strong>下界</strong>，节点必须要大于下界，小于上界，那么上界和下界从哪里来？<em>当前节点就是左子树的上界，右子树的下界！</em>  然后递归左右子树就ok了</p>
<blockquote>
<p>这题其实还有一个坑，只不过我这个做法直接跳过了，题目的case中有的节点值是<code>Integer.MIN_VALUE</code>，和<code>Integer.MAX_VALUE</code>  ，如果上界下界直接用int来传递的话，很有可能递归初始调用就是这样的</p>
<p><code>return isValidBST(root,Integer.MIN_VALUE,Integer.MAX_VALUE);</code> 这就正中出题人下怀，所以我们这里用一个包装类型，这样我们只需要检测上界下界是不是null就可以了</p>
</blockquote>
<p><strong>解法二</strong></p>
<p>这个就利用了BST和中序遍历的关系，我们知道中序遍历是 <code>左-&gt;根-&gt;右</code>  这个顺序放到 BST中恰好就是一个升序的序列，所以我们就可以利用这个性质来判断二叉树是不是BST</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//BST的中序遍历一定是升序的</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isValidBST</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    LinkedList&lt;Integer&gt; order=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">while</span>(cur!=<span class="keyword">null</span> || !stack.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.add(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        <span class="comment">//和上一次的最后一个节点值比较</span></span><br><span class="line">        <span class="keyword">if</span> (!order.isEmpty() &amp;&amp; order.getLast()&gt;= cur.val) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        order.add(cur.val);</span><br><span class="line">        cur=cur.right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里其实可以不用list保存结果，<del>用一个int保存上一次的节点值就行了</del> md重做的时候因为这个WA了好几次，如果用int的话需要加一个标志位用来初始化</p>
<h2 id="958-二叉树的完全性检验"><a href="#958-二叉树的完全性检验" class="headerlink" title="958. 二叉树的完全性检验"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/check-completeness-of-a-binary-tree/" >958. 二叉树的完全性检验<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给定一个二叉树，确定它是否是一个_完全二叉树_。</p>
<p><strong>中对完全二叉树的定义如下：</strong></p>
<p>若设二叉树的深度为 h，除第 h 层外，其它各层 (1～h-1) 的结点数都达到最大个数，第 h 层所有的结点都连续集中在最左边，这就是完全二叉树。（注：第 h 层可能包含 1~ 2<sup>h</sup> 个节点。）</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/complete-binary-tree-1.png"
                     
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]</span><br><span class="line">输出：<span class="literal">true</span></span><br><span class="line">解释：最后一层前的每一层都是满的（即，结点值为 &#123;<span class="number">1</span>&#125; 和 &#123;<span class="number">2</span>,<span class="number">3</span>&#125; 的两层），且最后一层中的所有结点（&#123;<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>&#125;）都尽可能地向左。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><strong><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/complete-binary-tree-2.png"
                     
                ></strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,null,<span class="number">7</span>]</span><br><span class="line">输出：<span class="literal">false</span></span><br><span class="line">解释：值为 <span class="number">7</span> 的结点没有尽可能靠向左侧。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li> 树中将会有 1 到 100 个结点。</li>
</ol>
<p><strong>解法一</strong></p>
<p>一开始思路出现了问题，想着去按照节点个数去校验，然后对最后一层做特判，然后发现这种思路是死胡同，实际上判断是否是完全二叉树很简单，只要节点<strong>中间</strong>没有出现null就说明是完全二叉树</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isCompleteTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    TreeNode pre = root;</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        TreeNode cur = queue.poll();</span><br><span class="line">        <span class="comment">//当前节点前面出现了null</span></span><br><span class="line">        <span class="keyword">if</span> (pre==<span class="keyword">null</span> &amp;&amp; cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (cur!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">//因为要判断null是否在中间，所以null节点也要存进去</span></span><br><span class="line">            queue.add(cur.left);</span><br><span class="line">            queue.add(cur.right);</span><br><span class="line">        &#125;</span><br><span class="line">        pre = cur;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="108-将有序数组转换为二叉搜索树"><a href="#108-将有序数组转换为二叉搜索树" class="headerlink" title="108. 将有序数组转换为二叉搜索树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/" >108. 将有序数组转换为二叉搜索树<i class="fas fa-external-link-alt"></i></a></h2><p>将一个按照升序排列的有序数组，转换为一棵<strong>高度平衡二叉搜索树</strong></p>
<p>本题中，一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">给定有序数组: [-<span class="number">10</span>,-<span class="number">3</span>,<span class="number">0</span>,<span class="number">5</span>,<span class="number">9</span>]</span><br><span class="line">一个可能的答案是：[<span class="number">0</span>,-<span class="number">3</span>,<span class="number">9</span>,-<span class="number">10</span>,<span class="keyword">null</span>,<span class="number">5</span>]，它可以表示下面这个高度平衡二叉搜索树：</span><br><span class="line">      <span class="number">0</span></span><br><span class="line">     / \</span><br><span class="line">   -<span class="number">3</span>   <span class="number">9</span></span><br><span class="line">   /   /</span><br><span class="line"> -<span class="number">10</span>  <span class="number">5</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">sortedArrayToBST</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> sortedArrayToBST(nums,<span class="number">0</span>,nums.length-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">sortedArrayToBST</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> left,<span class="keyword">int</span> right)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (left&gt;right) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> mid=(right-left)/<span class="number">2</span>+left;</span><br><span class="line">    TreeNode node=<span class="keyword">new</span> TreeNode(nums[mid]);</span><br><span class="line">    node.left=sortedArrayToBST(nums,left,mid-<span class="number">1</span>);</span><br><span class="line">    node.right=sortedArrayToBST(nums,mid+<span class="number">1</span>,right);</span><br><span class="line">    <span class="keyword">return</span> node;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题最开始终止条件写错了，思路是对的，对递归运用的还是不够熟练，终止条件其实只需要想一下极端情况就可以了</p>
<h2 id="109-有序链表转换二叉搜索树"><a href="#109-有序链表转换二叉搜索树" class="headerlink" title="109. 有序链表转换二叉搜索树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/" >109. 有序链表转换二叉搜索树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个单链表，其中的元素按升序排序，将其转换为高度平衡的二叉搜索树。</p>
<p>本题中，一个高度平衡二叉树是指一个二叉树<em>每个节点</em> 的左右两个子树的高度差的绝对值不超过 1。</p>
<p><strong>示例:</strong></p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">给定的有序链表： [<span class="number">-10</span>, <span class="number">-3</span>, <span class="number">0</span>, <span class="number">5</span>, <span class="number">9</span>],</span><br><span class="line"></span><br><span class="line">一个可能的答案是：[<span class="number">0</span>, <span class="number">-3</span>, <span class="number">9</span>, <span class="number">-10</span>, <span class="keyword">null</span>, <span class="number">5</span>], 它可以表示下面这个高度平衡二叉搜索树：</span><br><span class="line"></span><br><span class="line">      <span class="number">0</span></span><br><span class="line">     <span class="operator">/</span> \</span><br><span class="line">   <span class="number">-3</span>   <span class="number">9</span></span><br><span class="line">   <span class="operator">/</span>   <span class="operator">/</span></span><br><span class="line"> <span class="number">-10</span>  <span class="number">5</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p><del>BST不太熟看了下评论写出来的</del></p>
<p>好久之前写的题了，每日打卡题出了上面的题目，随便做一下这题，发现这题被记录在链表专题中了，移过来下，和上面的一样，只不过找中点的方式不一样（UPDATE: 2020.7.3）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">sortedListToBST</span><span class="params">(ListNode head)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> build(head,<span class="keyword">null</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> TreeNode <span class="title">build</span><span class="params">(ListNode head,ListNode tail)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(head==tail)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//快慢指针找中点</span></span><br><span class="line">    ListNode fast=head,slow=head;</span><br><span class="line">    <span class="keyword">while</span>(fast!=tail&amp;&amp;fast.next!=tail)&#123;</span><br><span class="line">        <span class="comment">//左闭右开</span></span><br><span class="line">        fast=fast.next.next;</span><br><span class="line">        slow=slow.next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//slow为中点或中点后一个</span></span><br><span class="line">    <span class="comment">//1 2 3 4</span></span><br><span class="line">    TreeNode root=<span class="keyword">new</span> TreeNode(slow.val);</span><br><span class="line">    root.left=build(head,slow);</span><br><span class="line">    root.right=build(slow.next,tail);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>UPDATE: 2020.7.3</strong></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">sortedListToBST</span><span class="params">(head *ListNode)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> head == <span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> head.Next == <span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> &amp;TreeNode&#123;Val : head.Val&#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> fast = head</span><br><span class="line">    <span class="keyword">var</span> slow = head <span class="comment">//slow为左中点</span></span><br><span class="line">    <span class="keyword">var</span> pre  = head</span><br><span class="line">    <span class="keyword">for</span> fast != <span class="literal">nil</span> &amp;&amp; fast.Next !=<span class="literal">nil</span>&#123;</span><br><span class="line">        fast = fast.Next.Next</span><br><span class="line">        pre = slow</span><br><span class="line">        slow = slow.Next</span><br><span class="line">    &#125;</span><br><span class="line">    pre.Next = <span class="literal">nil</span> <span class="comment">//斩断和slow的联系</span></span><br><span class="line">    root := &amp;TreeNode&#123;Val : slow.Val&#125;</span><br><span class="line">    root.Left = sortedListToBST(head)</span><br><span class="line">    root.Right = sortedListToBST(slow.Next)</span><br><span class="line">    <span class="keyword">return</span> root</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="230-二叉搜索树中第K小的元素"><a href="#230-二叉搜索树中第K小的元素" class="headerlink" title="230. 二叉搜索树中第K小的元素"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/" >230. 二叉搜索树中第K小的元素<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉搜索树，编写一个函数 <code>kthSmallest</code> 来查找其中第 k 个最小的元素</p>
<p><strong>说明：</strong><br>你可以假设 k 总是有效的，1 ≤ k ≤ 二叉搜索树元素个数。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: root = [<span class="number">3</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">2</span>], k = <span class="number">1</span></span><br><span class="line">   <span class="number">3</span></span><br><span class="line">  / \</span><br><span class="line"> <span class="number">1</span>   <span class="number">4</span></span><br><span class="line">  \</span><br><span class="line">   <span class="number">2</span></span><br><span class="line">输出: <span class="number">1</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: root = [<span class="number">5</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">1</span>], k = <span class="number">3</span></span><br><span class="line">       <span class="number">5</span></span><br><span class="line">      / \</span><br><span class="line">     <span class="number">3</span>   <span class="number">6</span></span><br><span class="line">    / \</span><br><span class="line">   <span class="number">2</span>   <span class="number">4</span></span><br><span class="line">  /</span><br><span class="line"> <span class="number">1</span></span><br><span class="line">输出: <span class="number">3</span></span><br></pre></td></tr></table></figure>


<p><strong>进阶：</strong><br>如果二叉搜索树经常被修改（插入/删除操作）并且你需要频繁地查找第 k 小的值，你将如何优化 kthSmallest 函数？</p>
<p><strong>解法一</strong></p>
<p>非递归中序遍历</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">kthSmallest</span><span class="params">(TreeNode root, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(cur!=<span class="keyword">null</span> || !stack.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.add(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        <span class="keyword">if</span> (count==k-<span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> cur.val;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=cur.right;</span><br><span class="line">        count++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//没找到</span></span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>还是利用BST中序遍历是升序的性质，在取到第k个元素的时候就直接<code>break</code></p>
<p><strong>解法二</strong></p>
<p>递归的方式，加了两个额外的实例变量其实不太好</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">kthSmallest</span><span class="params">(TreeNode root, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    kthSmallest(root,k);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">kthSmall</span><span class="params">(TreeNode root, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    kthSmall(root.left,k);</span><br><span class="line">    <span class="keyword">if</span> (count==k-<span class="number">1</span>) &#123;</span><br><span class="line">        res=root.val;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    count++;</span><br><span class="line">    kthSmall(root.right,k);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>如果是第K大就交换下遍历顺序就行了</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">kthLargest</span><span class="params">(root *TreeNode, k <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res = root.Val</span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span>&#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//先right</span></span><br><span class="line">        dfs(root.Right)</span><br><span class="line">        count++</span><br><span class="line">        <span class="keyword">if</span> count == k&#123;</span><br><span class="line">            res = root.Val</span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Left)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>进阶</strong></p>
<p>可以维护一个大根堆，就和最小栈一样，每次对BST操作的时候同步操作这个大根堆</p>
<h2 id="236-二叉树的最近公共祖先"><a href="#236-二叉树的最近公共祖先" class="headerlink" title="236. 二叉树的最近公共祖先"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/" >236. 二叉树的最近公共祖先<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。</p>
<p>百度百科中最近公共祖先的定义为：“对于有根树 T 的两个结点 p、q，最近公共祖先表示为一个结点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。”</p>
<p>例如，给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]</p>
<p> <img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191003/m0bWNSMUQWy2.png?imageslim"
                      alt="mark"
                ></p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: root = [<span class="number">3</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">8</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">7</span>,<span class="number">4</span>], p = <span class="number">5</span>, q = <span class="number">1</span></span><br><span class="line">输出: <span class="number">3</span></span><br><span class="line">解释: 节点 <span class="number">5</span> 和节点 <span class="number">1</span> 的最近公共祖先是节点 <span class="number">3</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: root = [<span class="number">3</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">8</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">7</span>,<span class="number">4</span>], p = <span class="number">5</span>, q = <span class="number">4</span></span><br><span class="line">输出: <span class="number">5</span></span><br><span class="line">解释: 节点 <span class="number">5</span> 和节点 <span class="number">4</span> 的最近公共祖先是节点 <span class="number">5</span>。因为根据定义最近公共祖先节点可以为节点本身。</span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<ul>
<li>所有节点的值都是唯一的。</li>
<li>p、q 为不同节点且均存在于给定的二叉树中。</li>
</ul>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">lowestCommonAncestor</span><span class="params">(TreeNode root, TreeNode p, TreeNode q)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span> || root==p || root==q) <span class="keyword">return</span> root; </span><br><span class="line">    TreeNode left=lowestCommonAncestor(root.left,p,q);</span><br><span class="line">    TreeNode right=lowestCommonAncestor(root.right,p,q);</span><br><span class="line">    <span class="keyword">if</span>(left==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> right;</span><br><span class="line">    &#125;<span class="keyword">else</span> <span class="keyword">if</span>(right==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> left;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个函数的功能有三个：给定两个节点 pp 和 qq</p>
<ul>
<li>如果 pp 和 qq 都存在，则返回它们的公共祖先</li>
<li>如果只存在一个，则返回存在的一个</li>
<li>如果 pp 和 qq 都不存在，则返回NULL </li>
</ul>
<p><strong>解法二</strong></p>
<p>2020.4.9新增解法，利用Map记录父节点，然后根据p,q倒推就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//update: 2020.5.10原来用的TreeNode做键，居然能过也是很神奇，我试了下，TreeNode应该是没有覆盖equals的</span></span><br><span class="line"><span class="comment">//所以要是碰撞的够多，那种做法就错了</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">lowestCommonAncestor</span><span class="params">(TreeNode root, TreeNode p, TreeNode q)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span> || p==root ||q==root) &#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    Deque&lt;TreeNode&gt; stack=<span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">    <span class="comment">//题目说了值唯一，所以可以用Integer当键</span></span><br><span class="line">    HashMap&lt;Integer,TreeNode&gt; map=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">    map.put(root.val,<span class="keyword">null</span>); <span class="comment">//根节点</span></span><br><span class="line">    stack.push(root);</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        TreeNode cur=stack.poll();</span><br><span class="line">        <span class="keyword">if</span>(cur.right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.push(cur.right);</span><br><span class="line">            map.put(cur.right.val,cur);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(cur.left!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.push(cur.left);</span><br><span class="line">            map.put(cur.left.val,cur);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    HashSet&lt;Integer&gt; set=<span class="keyword">new</span> HashSet&lt;&gt;();</span><br><span class="line">    <span class="keyword">while</span>(p!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        set.add(p.val);</span><br><span class="line">        p=map.get(p.val);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(!set.contains(q.val))&#123;</span><br><span class="line">        q=map.get(q.val);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> q;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="101-对称二叉树"><a href="#101-对称二叉树" class="headerlink" title="101. 对称二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/symmetric-tree/" >101. 对称二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，检查它是否是镜像对称的。</p>
<p>例如，二叉树 <code>[1,2,2,3,4,4,3]</code> 是对称的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">2</span></span><br><span class="line"> / \ / \</span><br><span class="line"><span class="number">3</span>  <span class="number">4</span> <span class="number">4</span>  <span class="number">3</span></span><br></pre></td></tr></table></figure>


<p>但是下面这个 <code>[1,2,2,null,3,null,3]</code> 则不是<strong>镜像对称</strong>的:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">1</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">2</span>   <span class="number">2</span></span><br><span class="line"> \   \</span><br><span class="line"> <span class="number">3</span>    <span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<p>如果你可以运用递归和迭代两种方法解决这个问题，会很加分。</p>
<p><strong>解法一</strong></p>
<p>哎，感觉刷题还是得在白天，脑子清醒点，下午就感觉做题老是出问题，一开始题都没看清就开始做</p>
<p>其实一开始是想BFS层次遍历然后判断每一层是不是镜像对称的，然后发现有些case是过不了的，比如</p>
<p><code>[1,3,3,2,null,2]</code> 这样的case</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">3</span>   <span class="number">3</span></span><br><span class="line"> /   /</span><br><span class="line"><span class="number">2</span>   <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><del>层序遍历判断不出了这样的case</del>   下面解法四打脸</p>
<p>然后换一种遍历方式，其实一开始就想到了前序遍历，如果是镜像对称的话，前序遍历刚好就是对称的，但是！！！还是有case过不了！！！我们再看上面的case，我们改一改</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">2</span></span><br><span class="line"> /   /</span><br><span class="line"><span class="number">2</span>   <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p>第<code>192/195个case</code>，我惊了，居然还有这种操作！！！实在没办法翻了下解答，发现有位老兄也是这样做的，然后他很巧妙的在每个节点值后面加了一个<strong>层数</strong>，他好像是直接当作字符串添加的，我感觉不太好，改用了数组，最后判断的时候需要保证层数和值都相同才行，完整代码如下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//[1,2,2,2,null,2] 忘了还有这样的case了,哭了</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSymmetric</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root == <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    List&lt;Integer[]&gt; lis=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    preTravle(root,lis,<span class="number">0</span>); </span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>,j=lis.size()-<span class="number">1</span>;i&lt;=j;i++,j--) &#123;</span><br><span class="line">        <span class="keyword">if</span> (lis.get(i)[<span class="number">0</span>]!= lis.get(j)[<span class="number">0</span>] ||  lis.get(j)[<span class="number">1</span>]!= lis.get(i)[<span class="number">1</span>]) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//前序遍历</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">preTravle</span><span class="params">(TreeNode node,List&lt;Integer[]&gt; lis,<span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        preTravle(node.left,lis,k+<span class="number">1</span>);</span><br><span class="line">        <span class="comment">//这里其实用个字符串就可以，但是感觉拼接的效率不高，而且，是不是有可能出现问题？</span></span><br><span class="line">        <span class="comment">// 11+3 ==1+13 ？？？是不是有可能出现类似这样的情况</span></span><br><span class="line">        Integer[] temp=<span class="keyword">new</span> Integer[<span class="number">2</span>];</span><br><span class="line">        temp[<span class="number">0</span>]=node.val;</span><br><span class="line">        temp[<span class="number">1</span>]=k;</span><br><span class="line">        lis.add(temp);</span><br><span class="line">        preTravle(node.right,lis,k+<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>递归的解法，应该算是官解了，一开始也是想用递归写的，没抓住问题的本质，太菜了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSymmetric</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//转换为求左右子树是否镜像对称的问题</span></span><br><span class="line">    <span class="keyword">return</span> isSymmetric(root.left,root.right);</span><br><span class="line">    <span class="comment">//return isSymmetric(root,root);</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//dfs</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSymmetric</span><span class="params">(TreeNode t1,TreeNode t2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (t1==<span class="keyword">null</span> &amp;&amp; t2==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//有一个为null</span></span><br><span class="line">    <span class="keyword">if</span> (t1== <span class="keyword">null</span> || t2==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//都不为null</span></span><br><span class="line">    <span class="keyword">return</span> t1.val==t2.val &amp;&amp; isSymmetric(t1.left,t2.right) &amp;&amp; isSymmetric(t1.right,t2.left);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>一棵树是镜像对称，说明左右子树左右对称，所以这个问题就可以转换为，判断左右两颗子树是否是镜像对称的问题</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191107/Ae6daB6SuXdl.png?imageslim"
                      alt="mark"
                ></p>
<p>判断两颗树是否成镜像对称的话，其实就和照镜子一样的，如上图，判断左子树和右子树是否成镜像对称，就需要判断<strong>t1的左子树和t2的右子树是否镜像对称,t1的右子树和t2的左子树是否镜像对称</strong>，根据这个就可以写出递归函数，还是挺妙的</p>
<p><strong>解法三</strong></p>
<p>类似于层次遍历，其实就是根据上面的递归方法改来的，核心思想和上面递归的是一样的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//非递归解法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSymmetric</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    stack.push(root.left);</span><br><span class="line">    stack.push(root.right);</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        TreeNode t1=stack.pop();</span><br><span class="line">        TreeNode t2=stack.pop();</span><br><span class="line">        <span class="keyword">if</span> (t1==<span class="keyword">null</span> &amp;&amp; t2==<span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (t1==<span class="keyword">null</span>||t2==<span class="keyword">null</span> || t1.val!=t2.val) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">/*if (t1.val!=t2.val) &#123;</span></span><br><span class="line"><span class="comment">                return false;</span></span><br><span class="line"><span class="comment">         &#125;*/</span></span><br><span class="line">        stack.push(t1.left);</span><br><span class="line">        stack.push(t2.right);</span><br><span class="line">        stack.push(t1.right);</span><br><span class="line">        stack.push(t2.left);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;       </span><br></pre></td></tr></table></figure>

<p><strong>解法四</strong></p>
<p>前序遍历，其实我一开始也想到了用占位的方式，但是因为之前遍历方式不同，导致没想好在哪里加</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isSymmetric</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        ArrayList&lt;Integer&gt; lis=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            <span class="comment">//lis.add(node.val);</span></span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">                lis.add(node.left.val);</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//-1占位</span></span><br><span class="line">                lis.add(-<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            </span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">                lis.add(node.right.val);</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//为空加-1占位</span></span><br><span class="line">                lis.add(-<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//对每一层经常判断</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>,j=lis.size()-<span class="number">1</span>;i&lt;=j;i++,j--) &#123;</span><br><span class="line">            <span class="keyword">if</span> (lis.get(i)!=lis.get(j)) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这样的做法明显时间复杂度会之前要高，不仅遍历了整颗树一遍，还对每一层遍历了一遍，一共遍历了两遍</p>
<h2 id="513-找树左下角的值"><a href="#513-找树左下角的值" class="headerlink" title="513. 找树左下角的值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-bottom-left-tree-value/" >513. 找树左下角的值<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，在树的最后一行找到最左边的值。</p>
<p>示例 1:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">    <span class="number">2</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">1</span>   <span class="number">3</span></span><br><span class="line">输出:</span><br><span class="line"><span class="number">1</span></span><br></pre></td></tr></table></figure>

<p>示例 2:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">        <span class="number">1</span></span><br><span class="line">       / \</span><br><span class="line">      <span class="number">2</span>   <span class="number">3</span></span><br><span class="line">     /   / \</span><br><span class="line">    <span class="number">4</span>   <span class="number">5</span>   <span class="number">6</span></span><br><span class="line">       /</span><br><span class="line">      <span class="number">7</span></span><br><span class="line">输出:</span><br><span class="line"><span class="number">7</span></span><br></pre></td></tr></table></figure>
<p><strong>注意:</strong> 您可以假设树（即给定的根节点）不为 NULL。</p>
<p><strong>解法一</strong></p>
<p>这种题写一百遍了😂，然而我还是没有bugfree</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//其实这种层序遍历的方式对这题有一点小题大作，不过我还是比较习惯这种方式</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findBottomLeftValue</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">int</span> res=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> count=queue.size();</span><br><span class="line">        <span class="keyword">int</span> temp=count;</span><br><span class="line">        <span class="keyword">while</span>(count&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode node=queue.poll();</span><br><span class="line">            <span class="keyword">if</span> (count==temp) &#123;</span><br><span class="line">                res=node.val;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.left);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(node.right);</span><br><span class="line">            &#125;</span><br><span class="line">            count--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;   </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>最左边的值，也就是最后一行的第一个元素，dfs深度优先，深度每增加一次就更新一次res</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//DFS</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findBottomLeftValue2</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    dfs(root,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res=-<span class="number">1</span>,max=Integer.MIN_VALUE;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode node,<span class="keyword">int</span> depth)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">    <span class="keyword">if</span> (depth&gt;max) &#123;</span><br><span class="line">        max=depth;</span><br><span class="line">        res=node.val;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(node.left,depth+<span class="number">1</span>);</span><br><span class="line">    dfs(node.right,depth+<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="105-从前序与中序遍历序列构造二叉树"><a href="#105-从前序与中序遍历序列构造二叉树" class="headerlink" title="105. 从前序与中序遍历序列构造二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/" >105. 从前序与中序遍历序列构造二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>根据一棵树的前序遍历与中序遍历构造二叉树。</p>
<p><strong>注意:</strong><br>你可以假设树中没有重复的元素。</p>
<p>例如，给出</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">前序遍历 preorder = [<span class="number">3</span>,<span class="number">9</span>,<span class="number">20</span>,<span class="number">15</span>,<span class="number">7</span>]</span><br><span class="line">中序遍历 inorder = [<span class="number">9</span>,<span class="number">3</span>,<span class="number">15</span>,<span class="number">20</span>,<span class="number">7</span>]</span><br></pre></td></tr></table></figure>


<p>返回如下的二叉树：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] preorder, <span class="keyword">int</span>[] inorder)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (preorder==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> buildTree(preorder,<span class="number">0</span>,preorder.length-<span class="number">1</span>,inorder,<span class="number">0</span>,inorder.length-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] preorder,<span class="keyword">int</span> preleft,<span class="keyword">int</span> preright,<span class="keyword">int</span>[] inorder,<span class="keyword">int</span> inleft,<span class="keyword">int</span> inright)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//递归出口只需要想一下边界,比如只要一个节点的时候,很明显只有一个节点的时候这几个值都是 0</span></span><br><span class="line">    <span class="comment">//但是此时肯定不能返回null,所以这里递归出口不是大于等于,而是大于</span></span><br><span class="line">    <span class="keyword">if</span> (preleft&gt;preright || inleft&gt;inright) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode root=<span class="keyword">new</span> TreeNode(preorder[preleft]);</span><br><span class="line">    <span class="keyword">int</span> index=inleft;</span><br><span class="line">    <span class="keyword">while</span>(inorder[index] != preorder[preleft]) &#123;</span><br><span class="line">        index++;</span><br><span class="line">    &#125;</span><br><span class="line">    root.left=buildTree(preorder,preleft+<span class="number">1</span>,preleft+index-inleft,inorder,inleft,index-<span class="number">1</span>);</span><br><span class="line">    root.right=buildTree(preorder,preleft+index-inleft+<span class="number">1</span>,preright,inorder,index+<span class="number">1</span>,inright);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题核心思想就是利用这几种遍历的性质，文字总是苍白的，看个图吧</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191106/pcmvnEK8Hwg8.png?imageslim"
                      alt="mark"
                ></p>
<p>这样一看就清晰了，前序遍历左边第一个节点 <code>1</code> 一定是根节点，所以我们首先确定了根节点，然后我们去中序遍历中去找这个根节点（一定有），如上图，我们找到了中间的 <code>1</code>然后再根据中序遍历的性质，我们可以就知道，中序遍历中，这个<code>1</code> 的左边是 <code>1</code> 的左子树，右边是<code>1</code> 的右子树，到这里我们就确定了根节点及其左右子树，剩下的就交给递归去完成了😁，我们只需要对左右子树分别递归该过程就可以得到一颗完整的树了</p>
<p>当然这里值得注意的地方就是下标的变换，要十分注意，自己带入几个值试试</p>
<p><strong>UPDATE(2020.5.22)</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> m <span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">int</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">buildTree</span><span class="params">(preorder []<span class="keyword">int</span>, inorder []<span class="keyword">int</span>)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    n:=<span class="built_in">len</span>(inorder)</span><br><span class="line">    <span class="comment">//m:=make(map[int]int,n) 靠！这个bug看了半天</span></span><br><span class="line">    m=<span class="built_in">make</span>(<span class="keyword">map</span>[<span class="keyword">int</span>]<span class="keyword">int</span>,n)</span><br><span class="line">    <span class="keyword">for</span> i,val:=<span class="keyword">range</span> inorder&#123;</span><br><span class="line">        m[val]=i</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> build(preorder,<span class="number">0</span>,n<span class="number">-1</span>,inorder,<span class="number">0</span>,n<span class="number">-1</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">build</span><span class="params">(pre []<span class="keyword">int</span>,pl <span class="keyword">int</span>,pr <span class="keyword">int</span>,in []<span class="keyword">int</span>,il <span class="keyword">int</span>,ir <span class="keyword">int</span>)</span> *<span class="title">TreeNode</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> pl&gt;pr || il&gt;ir&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    root:=&amp;TreeNode&#123;Val:pre[pl]&#125;</span><br><span class="line">    idx:=m[pre[pl]]</span><br><span class="line">    root.Left=build(pre,pl+<span class="number">1</span>,pl+idx-il,in,il,idx<span class="number">-1</span>)</span><br><span class="line">    root.Right=build(pre,pl+idx-il+<span class="number">1</span>,pr,in,idx+<span class="number">1</span>,ir)</span><br><span class="line">    <span class="keyword">return</span> root</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="106-从中序与后序遍历序列构造二叉树"><a href="#106-从中序与后序遍历序列构造二叉树" class="headerlink" title="106. 从中序与后序遍历序列构造二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/" >106. 从中序与后序遍历序列构造二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>根据一棵树的中序遍历与后序遍历构造二叉树。</p>
<p><strong>注意:</strong><br>你可以假设树中没有重复的元素。</p>
<p>例如，给出</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">中序遍历 inorder = [<span class="number">9</span>,<span class="number">3</span>,<span class="number">15</span>,<span class="number">20</span>,<span class="number">7</span>]</span><br><span class="line">后序遍历 postorder = [<span class="number">9</span>,<span class="number">15</span>,<span class="number">7</span>,<span class="number">20</span>,<span class="number">3</span>]</span><br></pre></td></tr></table></figure>


<p>返回如下的二叉树：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>
<p><strong>解法一</strong></p>
<p>方法同上，只不过是从后往前了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] inorder, <span class="keyword">int</span>[] postorder)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (inorder==<span class="keyword">null</span> || inorder.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> buildTree(inorder,<span class="number">0</span>,inorder.length-<span class="number">1</span>,postorder,<span class="number">0</span>,postorder.length-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] inorder,<span class="keyword">int</span> inL,<span class="keyword">int</span> inR, <span class="keyword">int</span>[] postorder,<span class="keyword">int</span> pL,<span class="keyword">int</span> pR)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//递归出口只需要想一下边界,比如只要一个节点的时候,很明显只有一个节点的时候这几个值都是0</span></span><br><span class="line">    <span class="comment">//但是此时肯定不能返回null,所以这里递归出口不是大于等于,而是大于</span></span><br><span class="line">    <span class="keyword">if</span> (inL&gt;inR || pL&gt;pR) &#123; </span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode root=<span class="keyword">new</span> TreeNode(postorder[pR]);</span><br><span class="line">    <span class="keyword">int</span> index=inL;</span><br><span class="line">    <span class="keyword">while</span>(inorder[index]!=postorder[pR])&#123;</span><br><span class="line">        index++; <span class="comment">//一定有,所以不用担心越界的问题</span></span><br><span class="line">    &#125;</span><br><span class="line">    root.left=buildTree(inorder,inL,index-<span class="number">1</span>,postorder,pL,pL+index-inL-<span class="number">1</span>);</span><br><span class="line">    root.right=buildTree(inorder,index+<span class="number">1</span>,inR,postorder,pL+index-inL,pR-<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>和上面一样没啥好说的</p>
<p><strong>解法二</strong></p>
<p>上面两种解法提交后效率都不高，这里去中序遍历中找根节点的操作其实可以用Hash表代替</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//hash表优化</span></span><br><span class="line">HashMap&lt;Integer,Integer&gt; map=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] inorder, <span class="keyword">int</span>[] postorder)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (inorder==<span class="keyword">null</span> || inorder.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;inorder.length;i++) &#123;</span><br><span class="line">        map.put(inorder[i],i);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> buildTree(inorder,<span class="number">0</span>,inorder.length-<span class="number">1</span>,postorder,<span class="number">0</span>,postorder.length-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] inorder,<span class="keyword">int</span> inL,<span class="keyword">int</span> inR, <span class="keyword">int</span>[] postorder,<span class="keyword">int</span> pL,<span class="keyword">int</span> pR)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//递归出口只需要想一下边界,比如只要一个节点的时候,很明显只有一个节点的时候这几个值都是相等的</span></span><br><span class="line">    <span class="comment">//但是此时肯定不能返回null,所以这里递归出口不是大于等于,而是大于</span></span><br><span class="line">    <span class="keyword">if</span> (inL&gt;inR || pL&gt;pR) &#123; </span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode root=<span class="keyword">new</span> TreeNode(postorder[pR]);</span><br><span class="line">    <span class="keyword">int</span> index=map.get(postorder[pR]);</span><br><span class="line">    root.left=buildTree(inorder,inL,index-<span class="number">1</span>,postorder,pL,pL+index-inL-<span class="number">1</span>);</span><br><span class="line">    root.right=buildTree(inorder,index+<span class="number">1</span>,inR,postorder,pL+index-inL,pR-<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="889-根据前序和后序遍历构造二叉树"><a href="#889-根据前序和后序遍历构造二叉树" class="headerlink" title="889. 根据前序和后序遍历构造二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/" >889. 根据前序和后序遍历构造二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>返回与给定的前序和后序遍历匹配的任何二叉树。</p>
<p> pre 和 post 遍历中的值是不同的正整数。</p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：pre = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">7</span>], post = [<span class="number">4</span>,<span class="number">5</span>,<span class="number">2</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">3</span>,<span class="number">1</span>]</span><br><span class="line">输出：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>]</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= pre.length == post.length &lt;= 30</code></li>
<li><code>pre[]</code> 和 <code>post[]</code> 都是 1, 2, …, pre.length 的排列</li>
<li>每个输入保证至少有一个答案。如果有多个答案，可以返回其中一个。</li>
</ul>
<p><strong>解法一</strong></p>
<p>和上面的有一点点区别</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">HashMap&lt;Integer,Integer&gt; map=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">constructFromPrePost</span><span class="params">(<span class="keyword">int</span>[] pre, <span class="keyword">int</span>[] post)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;post.length;i++) &#123;</span><br><span class="line">        map.put(post[i],i);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> constructFromPrePost(pre,<span class="number">0</span>,pre.length-<span class="number">1</span>,post,<span class="number">0</span>,post.length-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">constructFromPrePost</span><span class="params">(<span class="keyword">int</span>[] pre,<span class="keyword">int</span> preL,<span class="keyword">int</span> preR,<span class="keyword">int</span>[] post,<span class="keyword">int</span> postL,<span class="keyword">int</span> postR)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (preL&gt;preR || postL&gt;preR) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode root=<span class="keyword">new</span> TreeNode(pre[preL]);</span><br><span class="line">    <span class="keyword">if</span> (preL==preR) &#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> postIndex=map.get(pre[preL+<span class="number">1</span>]); <span class="comment">//这种位置一定要注意溢出</span></span><br><span class="line">    <span class="keyword">int</span> len=postIndex-postL;</span><br><span class="line">    root.left=constructFromPrePost(pre,preL+<span class="number">1</span>,preL+<span class="number">1</span>+len,post,postL,postIndex);</span><br><span class="line">    root.right=constructFromPrePost(pre,preL+<span class="number">2</span>+len,preR,post,postIndex+<span class="number">1</span>,postR-<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191106/pcmvnEK8Hwg8.png?imageslim"
                      alt="mark"
                ></p>
<p>还是这张图，前序的第一个是根节点，后序的最后一个是根节点，而我们要找的是左右子树的分界线，这里没有中序遍历，乍一看似乎不好确定，其实不然，注意观察前序的第二个节点，也就是左子树的根节点，比如上面的2，对应到后序遍历中其实正好就可以作为左子树的分界线，这样一来就和上面一样了，所以这里的关键就是找到一个划分点</p>
<p>🔔 <strong>有一点需要注意，题目说了这题的结果可能是不唯一的，数据结构的课程里面也讲过，仅凭前序和后序是无法确定一颗二叉树的，但是一定么？</strong></p>
<p>并不一定，我们题目的case就是个反例，它就可以通过前序和后序唯一的确定这颗二叉树，那什么时候可以确定，什么时候无法确定呢？</p>
<p>无法确定的例子好说，【1，2】，【2，1】这个就无法确定</p>
 <figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">1</span>              <span class="number">1</span>   </span><br><span class="line"> \            /</span><br><span class="line">  <span class="number">2</span>          <span class="number">2</span>        两种可能都有</span><br></pre></td></tr></table></figure>

<p> 但是如果是这样的【1，2，3】【2，3，1】这种就可以唯一的确定</p>
 <figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">1</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">2</span>   <span class="number">3</span>  只可能是这种情况</span><br></pre></td></tr></table></figure>
<p>归纳总结一下，可以发现，<strong>如果这颗二叉树每个节点的度都是0或者2</strong> 那么他就可以通过前序和后序确定，反之就不一定了，因为你只有一个子节点那么就无法确定这个节点是左节点还是右节点，如果没有或者两个都有那么就可以确定了（根据顺序确定，前面的是左后面的是右，但是你只有一个我就不知道是左还是右了）</p>
<h2 id="114-二叉树展开为链表"><a href="#114-二叉树展开为链表" class="headerlink" title="114. 二叉树展开为链表"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/" >114. 二叉树展开为链表<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，原地将它展开为链表。</p>
<p>例如，给定二叉树</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">	<span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">5</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">3</span>   <span class="number">4</span>   <span class="number">6</span></span><br></pre></td></tr></table></figure>

<p>将其展开为：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">1</span></span><br><span class="line"> \</span><br><span class="line">  <span class="number">2</span></span><br><span class="line">   \</span><br><span class="line">    <span class="number">3</span></span><br><span class="line">     \</span><br><span class="line">      <span class="number">4</span></span><br><span class="line">       \</span><br><span class="line">        <span class="number">5</span></span><br><span class="line">         \</span><br><span class="line">          <span class="number">6</span></span><br></pre></td></tr></table></figure>

<blockquote>
<p>题目没抄错，就是这样的，确实题目没有说明按照什么方式展开，但是看case能猜到是前序遍历的方式展开（靠猜的？）</p>
</blockquote>
<p><strong>解法一</strong></p>
<p>前序遍历，递归的解法，用一个全局变量保存链表的结尾，每次将节点添加到last的后面</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">TreeNode last=<span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">flatten</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (last!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        last.left=<span class="keyword">null</span>;</span><br><span class="line">        last.right=root;</span><br><span class="line">    &#125;</span><br><span class="line">    last=root;</span><br><span class="line">    TreeNode right=root.right;<span class="comment">//保存右子树</span></span><br><span class="line">    flatten(root.left);</span><br><span class="line">    flatten(right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>需要注意的地方就是需要保存右子树，因为前面的操作将左子树添加到根节点右子树的时候，会导致原本的右子树丢失</p>
<p><strong>非递归的写法</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">flatten</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">    TreeNode last=<span class="keyword">null</span>;</span><br><span class="line">    Deque&lt;TreeNode&gt; stack=<span class="keyword">new</span> ArrayDeque&lt;&gt;();</span><br><span class="line">    stack.push(root);</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty())&#123;</span><br><span class="line">        TreeNode cur=stack.pop();</span><br><span class="line">        <span class="keyword">if</span>(last!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            last.right=cur;</span><br><span class="line">            last.left=<span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        last=cur;</span><br><span class="line">        <span class="keyword">if</span>(cur.right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.push(cur.right);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(cur.left!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.push(cur.left);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>变形的后序遍历，递归解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">TreeNode pre=<span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">flatten</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    flatten(root.right);</span><br><span class="line">    flatten(root.left);</span><br><span class="line">    root.right=pre;</span><br><span class="line">    root.left=<span class="keyword">null</span>;</span><br><span class="line">    pre=root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>相比前面的解法，为了不丢失右子树，先遍历右子树，再遍历左子树，整个序列就是<code>6 5 4 3 2 1</code>  我们只需要将每个节点的right指向前一个节点就ok了</p>
<p><strong>解法三</strong></p>
<p>迭代，我觉得这种解法挺秀，而且是完全的 <code>in-place</code>，但是时间复杂度会高一些，每个元素不只遍历一次</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">flatten</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    TreeNode mRight=<span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">while</span>(root!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span> (root.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            mRight=root.left;</span><br><span class="line">            <span class="comment">//找到左子树的最右节点</span></span><br><span class="line">            <span class="keyword">while</span>(mRight.right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">                mRight=mRight.right;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//将根的右节点接在 mRight.right</span></span><br><span class="line">            mRight.right=root.right;</span><br><span class="line">            <span class="comment">//将root.left接在root.right</span></span><br><span class="line">            root.right=root.left;</span><br><span class="line">            <span class="comment">//左节点置为null</span></span><br><span class="line">            root.left=<span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//重复该过程</span></span><br><span class="line">        root=root.right;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>画个图就是这样</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20191108/BIx12P1AYjeX.png?imageslim"
                      alt="mark"
                ></p>
<h2 id="面试题36-二叉搜索树与双向链表"><a href="#面试题36-二叉搜索树与双向链表" class="headerlink" title="面试题36. 二叉搜索树与双向链表"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/" >面试题36. 二叉搜索树与双向链表<i class="fas fa-external-link-alt"></i></a></h2><p>输入一棵二叉搜索树，将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点，只能调整树中节点指针的指向。</p>
<p>为了让您更好地理解问题，以下面的二叉搜索树为例：</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s2.ax1x.com/2020/02/19/3VE7QO.png"
                      alt="3VE7QO.png"
                ></p>
<p>我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表，第一个节点的前驱是最后一个节点，最后一个节点的后继是第一个节点。</p>
<p>下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。<br><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/06/18/Nn3iZR.png"
                      alt="Nn3iZR.png"
                ><br>特别地，我们希望可以就地完成转换操作。当转化完成以后，树中节点的左指针需要指向前驱，树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。</p>
<p><strong>解法一</strong></p>
<p>开始还以为挺难搞，一遍就写出来了😁比上一题简单</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Node <span class="title">treeToDoublyList</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> root;</span><br><span class="line">    dfs(root);</span><br><span class="line">    head.left=lastNode;</span><br><span class="line">    lastNode.right=head;</span><br><span class="line">    <span class="keyword">return</span> head;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Node lastNode,head=<span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(Node root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span>;</span><br><span class="line">    dfs(root.left);</span><br><span class="line">    <span class="keyword">if</span>(lastNode==<span class="keyword">null</span>)&#123;</span><br><span class="line">        head=lastNode=root;</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        root.left=lastNode;</span><br><span class="line">        lastNode.right=root;</span><br><span class="line">        lastNode=root;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="116-填充每个节点的下一个右侧节点指针"><a href="#116-填充每个节点的下一个右侧节点指针" class="headerlink" title="116. 填充每个节点的下一个右侧节点指针"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/" >116. 填充每个节点的下一个右侧节点指针<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个<strong>完美二叉树</strong>，其所有叶子节点都在同一层，每个父节点都有两个子节点。二叉树定义如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">struct Node &#123;</span><br><span class="line">  <span class="keyword">int</span> val;</span><br><span class="line">  Node *left;</span><br><span class="line">  Node *right;</span><br><span class="line">  Node *next;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<p>填充它的每个 next 指针，让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点，则将 next 指针设置为 NULL</p>
<p>初始状态下，所有 next 指针都被设置为 NULL</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2019/11/10/eC4VBqXmwuspZlG.png"
                      alt="leet"
                ></p>
<p><strong>解法一</strong></p>
<p>开始没做出来，菜！！！然后特意留到今天总结，又在web上提交了一遍</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Node <span class="title">connect</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span> ||root.left==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    root.left.next=root.right;</span><br><span class="line">    <span class="keyword">if</span> (root.next!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        root.right.next=root.next.left;   </span><br><span class="line">    &#125;</span><br><span class="line">    connect(root.left);</span><br><span class="line">    connect(root.right);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>这个解法梳理还是很清奇的，类似拉拉链的过程</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Node <span class="title">connect</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span> ||root.left==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    Node left=root.left;</span><br><span class="line">    Node right=root.right;</span><br><span class="line">    <span class="comment">//有的像拉拉链的过程</span></span><br><span class="line">    <span class="keyword">while</span>(left!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        left.next=right;</span><br><span class="line">        left=left.right;</span><br><span class="line">        right=right.left;</span><br><span class="line">    &#125;</span><br><span class="line">    connect(root.left);</span><br><span class="line">    connect(root.right);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>还有一个很直白的层序遍历的方法，这里就不写了</p>
</blockquote>
<h2 id="117-填充每个节点的下一个右侧节点指针-II"><a href="#117-填充每个节点的下一个右侧节点指针-II" class="headerlink" title="117. 填充每个节点的下一个右侧节点指针 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/" >117. 填充每个节点的下一个右侧节点指针 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">struct Node &#123;</span><br><span class="line">  <span class="keyword">int</span> val;</span><br><span class="line">  Node *left;</span><br><span class="line">  Node *right;</span><br><span class="line">  Node *next;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>填充它的每个 next 指针，让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点，则将 next 指针设置为 <code>NULL</code>。</p>
<p>初始状态下，所有 next 指针都被设置为 <code>NULL</code>。</p>
<p><strong>进阶：</strong></p>
<ul>
<li>你只能使用常量级额外空间。</li>
<li>使用递归解题也符合要求，本题中递归程序占用的栈空间不算做额外的空间复杂度。</li>
</ul>
<p><strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/20/Y7BwBd.png"
                      alt="Y7BwBd.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="keyword">null</span>,<span class="number">7</span>]</span><br><span class="line">输出：[<span class="number">1</span>,#,<span class="number">2</span>,<span class="number">3</span>,#,<span class="number">4</span>,<span class="number">5</span>,<span class="number">7</span>,#]</span><br><span class="line">解释：给定二叉树如图 A 所示，你的函数应该填充它的每个 next 指针，以指向其下一个右侧节点，如图 B 所示。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>树中的节点数小于 <code>6000</code></li>
<li><code>-100 &lt;= node.val &lt;= 100</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>题目要求的O(1)空间，参考了大佬的解法，模拟层序遍历，着实是很巧妙，代码简洁清晰，值得细细品味</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Node <span class="title">connect</span><span class="params">(Node root)</span> </span>&#123;</span><br><span class="line">    Node dummyNode=<span class="keyword">new</span> Node(-<span class="number">1</span>);</span><br><span class="line">    Node cur=root;</span><br><span class="line">    <span class="comment">//cur在上层，dummyNode和tail在下层，tail负责连接下层所有子节点</span></span><br><span class="line">    <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        dummyNode.next=<span class="keyword">null</span>; <span class="comment">//重置</span></span><br><span class="line">        Node tail=dummyNode;</span><br><span class="line">        <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(cur.left!=<span class="keyword">null</span>)&#123;</span><br><span class="line">                tail.next=cur.left;</span><br><span class="line">                tail=tail.next;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(cur.right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">                tail.next=cur.right;</span><br><span class="line">                tail=tail.next;</span><br><span class="line">            &#125;</span><br><span class="line">            cur=cur.next;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=dummyNode.next; <span class="comment">//cur转换到下一层</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="450-删除二叉搜索树中的节点"><a href="#450-删除二叉搜索树中的节点" class="headerlink" title="450. 删除二叉搜索树中的节点"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/delete-node-in-a-bst/" >450. 删除二叉搜索树中的节点<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉搜索树的根节点 root 和一个值 key，删除二叉搜索树中的 key 对应的节点，并保证二叉搜索树的性质不变。返回二叉搜索树（有可能被更新）的根节点的引用。</p>
<p>一般来说，删除节点可分为两个步骤：</p>
<ol>
<li><p>首先找到需要删除的节点；</p>
</li>
<li><p>如果找到了，删除它。</p>
</li>
</ol>
<p><strong>说明：</strong> 要求算法时间复杂度为 O(h)，h 为树的高度。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">root = [<span class="number">5</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">7</span>]</span><br><span class="line">key = <span class="number">3</span></span><br><span class="line"></span><br><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">3</span>   <span class="number">6</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">2</span>   <span class="number">4</span>   <span class="number">7</span></span><br><span class="line"></span><br><span class="line">给定需要删除的节点值是 <span class="number">3</span>，所以我们首先找到 <span class="number">3</span> 这个节点，然后删除它。</span><br><span class="line"></span><br><span class="line">一个正确的答案是 [<span class="number">5</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">7</span>], 如下图所示。</span><br><span class="line"></span><br><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">4</span>   <span class="number">6</span></span><br><span class="line"> /     \</span><br><span class="line"><span class="number">2</span>       <span class="number">7</span></span><br><span class="line"></span><br><span class="line">另一个正确答案是 [<span class="number">5</span>,<span class="number">2</span>,<span class="number">6</span>,<span class="keyword">null</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">7</span>]。</span><br><span class="line"></span><br><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">6</span></span><br><span class="line">   \   \</span><br><span class="line">    <span class="number">4</span>   <span class="number">7</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>更多解释看另一篇 <a href="http://imlgw.top/2019/11/08/er-fen-sou-suo-shu/#%E5%88%A0%E9%99%A4%E4%BB%BB%E6%84%8F%E5%80%BC">二叉搜索树</a></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">deleteNode</span><span class="params">(TreeNode root, <span class="keyword">int</span> key)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;           </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.val&gt;key) &#123;</span><br><span class="line">        root.left=deleteNode(root.left,key);</span><br><span class="line">    &#125;<span class="keyword">else</span> <span class="keyword">if</span> (root.val&lt;key) &#123;</span><br><span class="line">        root.right=deleteNode(root.right,key);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (root.left==<span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> root.right;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> root.left;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//用右子树的最小值填补删除的元素</span></span><br><span class="line">        TreeNode delNode=root;</span><br><span class="line">        root=getMin(root.right);</span><br><span class="line">        <span class="comment">//下面的left和right不能交换,还好刚开始写错了一波,不然也不会发现,哈哈啊哈哈哈</span></span><br><span class="line">        <span class="comment">//这里的deleteMin是为了删除delNode的最小值root,如果你先把delNode.left连接到了root.left</span></span><br><span class="line">        <span class="comment">//那么root就不再是最小值了,再进行deleteMin就会导致root无法删除,最后返回root,导致root.right=root形成环</span></span><br><span class="line">        <span class="comment">//结果无法打印</span></span><br><span class="line">        root.right=deleteMin(delNode.right);</span><br><span class="line">        root.left=delNode.left;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">deleteMin</span><span class="params">(TreeNode node)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node.left==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> node.right;</span><br><span class="line">    &#125;</span><br><span class="line">    node.left=deleteMin(node.left);</span><br><span class="line">    <span class="keyword">return</span> node;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">getMin</span><span class="params">(TreeNode node)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node.left==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> node;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> getMin(node.left);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="701-二叉搜索树中的插入操作"><a href="#701-二叉搜索树中的插入操作" class="headerlink" title="701. 二叉搜索树中的插入操作"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/" >701. 二叉搜索树中的插入操作<i class="fas fa-external-link-alt"></i></a></h2><p>给定二叉搜索树（BST）的根节点和要插入树中的值，将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 保证原始二叉搜索树中不存在新值。</p>
<p>注意，可能存在多种有效的插入方式，只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。</p>
<p>例如, </p>
<p>给定二叉搜索树:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">4</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">7</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">3</span></span><br><span class="line"></span><br><span class="line">和 插入的值: <span class="number">5</span></span><br></pre></td></tr></table></figure>


<p>你可以返回这个二叉搜索树:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">     <span class="number">4</span></span><br><span class="line">   /   \</span><br><span class="line">  <span class="number">2</span>     <span class="number">7</span></span><br><span class="line"> / \   /</span><br><span class="line"><span class="number">1</span>   <span class="number">3</span> <span class="number">5</span></span><br></pre></td></tr></table></figure>
<p>或者这个树也是有效的:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">     <span class="number">5</span></span><br><span class="line">   /   \</span><br><span class="line">  <span class="number">2</span>     <span class="number">7</span></span><br><span class="line"> / \   </span><br><span class="line"><span class="number">1</span>   <span class="number">3</span></span><br><span class="line">     \</span><br><span class="line">      <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">insertIntoBST</span><span class="params">(TreeNode root, <span class="keyword">int</span> val)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(val);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.val&gt;val) &#123;</span><br><span class="line">        root.left=insertIntoBST(root.left,val);   </span><br><span class="line">    &#125;<span class="keyword">else</span> <span class="keyword">if</span> (root.val&lt;val) &#123;</span><br><span class="line">        root.right=insertIntoBST(root.right,val);   </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>没啥好说的，看代码就懂了</p>
<h2 id="662-二叉树最大宽度"><a href="#662-二叉树最大宽度" class="headerlink" title="662. 二叉树最大宽度"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-width-of-binary-tree/" >662. 二叉树最大宽度<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。<strong>这个二叉树与满二叉树（full binary tree）结构相同，但一些节点为空。</strong></p>
<p>每一层的宽度被定义为两个端点（该层最左和最右的非空节点，两端点间的null节点也计入长度）之间的长度。</p>
<p><strong>Example 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: </span><br><span class="line"></span><br><span class="line">           <span class="number">1</span></span><br><span class="line">         /   \</span><br><span class="line">        <span class="number">3</span>     <span class="number">2</span></span><br><span class="line">       / \     \  </span><br><span class="line">      <span class="number">5</span>   <span class="number">3</span>     <span class="number">9</span> </span><br><span class="line"></span><br><span class="line">Output: <span class="number">4</span></span><br><span class="line">Explanation: The maximum width existing in the third level with the length <span class="number">4</span> (<span class="number">5</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">9</span>).</span><br></pre></td></tr></table></figure>

<p><strong>Example 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: </span><br><span class="line"></span><br><span class="line">          <span class="number">1</span></span><br><span class="line">         /  </span><br><span class="line">        <span class="number">3</span>    </span><br><span class="line">       / \       </span><br><span class="line">      <span class="number">5</span>   <span class="number">3</span>     </span><br><span class="line"></span><br><span class="line">Output: <span class="number">2</span></span><br><span class="line">Explanation: The maximum width existing in the third level with the length <span class="number">2</span> (<span class="number">5</span>,<span class="number">3</span>).</span><br></pre></td></tr></table></figure>

<p><strong>Example 3:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: </span><br><span class="line"></span><br><span class="line">          <span class="number">1</span></span><br><span class="line">         / \</span><br><span class="line">        <span class="number">3</span>   <span class="number">2</span> </span><br><span class="line">       /        </span><br><span class="line">      <span class="number">5</span>      </span><br><span class="line"></span><br><span class="line">Output: <span class="number">2</span></span><br><span class="line">Explanation: The maximum width existing in the second level with the length <span class="number">2</span> (<span class="number">3</span>,<span class="number">2</span>).</span><br></pre></td></tr></table></figure>

<p><strong>Example 4:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Input: </span><br><span class="line"></span><br><span class="line">          <span class="number">1</span></span><br><span class="line">         / \</span><br><span class="line">        <span class="number">3</span>   <span class="number">2</span></span><br><span class="line">       /     \  </span><br><span class="line">      <span class="number">5</span>       <span class="number">9</span> </span><br><span class="line">     /         \</span><br><span class="line">    <span class="number">6</span>           <span class="number">7</span></span><br><span class="line">Output: <span class="number">8</span></span><br><span class="line">Explanation:The maximum width existing in the fourth level with the length <span class="number">8</span> (<span class="number">6</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">7</span>).</span><br></pre></td></tr></table></figure>

<p><strong>Note:</strong> Answer will in the range of 32-bit signed integer.</p>
<p><strong>解法一</strong></p>
<p>一开始居然没想到，哎😐还是菜啊</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">widthOfBinaryTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    LinkedList&lt;Integer&gt; idxs=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">1</span>;</span><br><span class="line">    idxs.add(<span class="number">1</span>);</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        <span class="keyword">int</span> size=queue.size();</span><br><span class="line">        <span class="keyword">while</span>(size&gt;<span class="number">0</span>)&#123;</span><br><span class="line">            TreeNode top=queue.poll();</span><br><span class="line">            <span class="keyword">int</span> index=idxs.removeFirst();</span><br><span class="line">            <span class="keyword">if</span> (top.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(top.left);</span><br><span class="line">                idxs.add(index*<span class="number">2</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (top.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">                queue.add(top.right);</span><br><span class="line">                idxs.add(index*<span class="number">2</span>+<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            size--;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (idxs.size()!=<span class="number">0</span>) &#123;</span><br><span class="line">            max=Math.max(idxs.getLast()-idxs.getFirst()+<span class="number">1</span>,max);    </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>还是层次遍历的思路，不过需要额外添加一个索引列表，用来<strong>记录每个节点对应在完全二叉树中的索引</strong>，这个索引值完全可以根据上一层父节点的索引的到，我们初始化定义根节点的index为1，然后进行层次遍历记录每一层的每个节点的index就ok，当遍历完一层之后统计列表最左和最右两个节点之差，这个值就是当前层的宽度，最后求个最大值就ok了，很可惜，看了答案才知道</p>
<p><strong>解法二</strong></p>
<p>递归版本</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">widthOfBinaryTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root,<span class="number">0</span>,<span class="number">0</span>,<span class="keyword">new</span> LinkedList&lt;&gt;());</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> max=<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode node,<span class="keyword">int</span> depth,<span class="keyword">int</span> index,List&lt;Integer&gt; leftIdxs)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (depth&gt;=leftIdxs.size()) &#123;</span><br><span class="line">        leftIdxs.add(index);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//记录当前节点和当前层最左节点的差</span></span><br><span class="line">    max=Math.max(index-leftIdxs.get(depth)+<span class="number">1</span>,max);</span><br><span class="line">    dfs(node.left,depth+<span class="number">1</span>,index*<span class="number">2</span>,leftIdxs);</span><br><span class="line">    dfs(node.right,depth+<span class="number">1</span>,index*<span class="number">2</span>+<span class="number">1</span>,leftIdxs);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这个版本在空间复杂度可能会低一点，list中只存每个层最左的节点，当深度大于等于list的长度时候说明当前节点一定是新一层的最左节点，这个时候添加进去就ok，然后求每个节点和当前层最左的节点index差值就最后更新最大值就ok，这个解法还是没有那么自然，还是上面的BFS好理解一点</p>
<h2 id="671-二叉树中第二小的节点"><a href="#671-二叉树中第二小的节点" class="headerlink" title="671. 二叉树中第二小的节点"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree/" >671. 二叉树中第二小的节点<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个非空特殊的二叉树，每个节点都是正数，并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话，那么这个节点的值不大于它的子节点的值。 </p>
<p>给出这样的一个二叉树，你需要输出所有节点中的第二小的值。如果第二小的值不存在的话，输出 -1 。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    <span class="number">2</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">5</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">5</span>   <span class="number">7</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">5</span></span><br><span class="line">说明: 最小的值是 <span class="number">2</span> ，第二小的值是 <span class="number">5</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    <span class="number">2</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出: -<span class="number">1</span></span><br><span class="line">说明: 最小的值是 <span class="number">2</span>, 但是不存在第二小的值。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="comment">//自然的从上到下的思路</span></span><br><span class="line"><span class="keyword">var</span> INT_MAX = <span class="keyword">int</span>(^<span class="keyword">uint</span>(<span class="number">0</span>) &gt;&gt; <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findSecondMinimumValue</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">	res := dfs(root)</span><br><span class="line">	<span class="keyword">if</span> res == INT_MAX &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">	<span class="keyword">if</span> root == <span class="literal">nil</span> || root.Left == <span class="literal">nil</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> INT_MAX</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//和左右子树都不等，谁小就是谁</span></span><br><span class="line">	<span class="keyword">if</span> root.Val != root.Left.Val &amp;&amp; root.Val != root.Right.Val &#123;</span><br><span class="line">		<span class="keyword">return</span> min(root.Left.Val, root.Right.Val)</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//和左右子树都相等，分别在左右子树中找第二小比较</span></span><br><span class="line">	<span class="keyword">if</span> root.Val == root.Left.Val &amp;&amp; root.Val == root.Right.Val &#123;</span><br><span class="line">		<span class="keyword">return</span> min(dfs(root.Left), dfs(root.Right))</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//和左子树相等,在左子树中找第二小和右子树比较</span></span><br><span class="line">	<span class="keyword">if</span> root.Val == root.Left.Val &#123;</span><br><span class="line">		<span class="keyword">return</span> min(dfs(root.Left), root.Right.Val)</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//同上</span></span><br><span class="line">	<span class="keyword">return</span> min(dfs(root.Right), root.Left.Val)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">min</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">	<span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">		<span class="keyword">return</span> b</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> a</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="938-二叉搜索树的范围和"><a href="#938-二叉搜索树的范围和" class="headerlink" title="938. 二叉搜索树的范围和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/range-sum-of-bst/" >938. 二叉搜索树的范围和<i class="fas fa-external-link-alt"></i></a></h2><p>给定二叉搜索树的根结点 root，返回 L 和 R（含）之间的所有结点的值的和。</p>
<p>二叉搜索树保证具有唯一的值。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">10</span>,<span class="number">5</span>,<span class="number">15</span>,<span class="number">3</span>,<span class="number">7</span>,<span class="keyword">null</span>,<span class="number">18</span>], L = <span class="number">7</span>, R = <span class="number">15</span></span><br><span class="line">输出：<span class="number">32</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">10</span>,<span class="number">5</span>,<span class="number">15</span>,<span class="number">3</span>,<span class="number">7</span>,<span class="number">13</span>,<span class="number">18</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">6</span>], L = <span class="number">6</span>, R = <span class="number">10</span></span><br><span class="line">输出：<span class="number">23</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>树中的结点数量最多为 10000 个。</li>
<li>最终的答案保证小于 2^31</li>
</ul>
<p><strong>解法一</strong></p>
<p>还行，这题反应过来了，中序遍历</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">rangeSumBST</span><span class="params">(TreeNode root, <span class="keyword">int</span> L, <span class="keyword">int</span> R)</span> </span>&#123;</span><br><span class="line">    preorder(root,L,R);</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">preorder</span><span class="params">(TreeNode root, <span class="keyword">int</span> L, <span class="keyword">int</span> R)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    rangeSumBST(root.left,L,R);</span><br><span class="line">    <span class="keyword">if</span> (root.val&gt;=L &amp;&amp; root.val&lt;=R) &#123;</span><br><span class="line">        sum+=root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    rangeSumBST(root.right,L,R);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="617-合并二叉树"><a href="#617-合并二叉树" class="headerlink" title="617. 合并二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/merge-two-binary-trees/" >617. 合并二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>给定两个二叉树，想象当你将它们中的一个覆盖到另一个上时，两个二叉树的一些节点便会重叠。</p>
<p>你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠，那么将他们的值相加作为节点合并后的新值，否则不为 NULL 的节点将直接作为新二叉树的节点。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">	Tree <span class="number">1</span>                     Tree <span class="number">2</span>                  </span><br><span class="line">          <span class="number">1</span>                         <span class="number">2</span>                             </span><br><span class="line">         / \                       / \                            </span><br><span class="line">        <span class="number">3</span>   <span class="number">2</span>                     <span class="number">1</span>   <span class="number">3</span>                        </span><br><span class="line">       /                           \   \                      </span><br><span class="line">      <span class="number">5</span>                             <span class="number">4</span>   <span class="number">7</span>                  </span><br><span class="line">输出: </span><br><span class="line">合并后的树:</span><br><span class="line">	     <span class="number">3</span></span><br><span class="line">	    / \</span><br><span class="line">	   <span class="number">4</span>   <span class="number">5</span></span><br><span class="line">	  / \   \ </span><br><span class="line">	 <span class="number">5</span>   <span class="number">4</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong> 合并必须从两个树的根节点开始。</p>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">mergeTrees</span><span class="params">(TreeNode t1, TreeNode t2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (t2==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>  t1;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (t1==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> t2;</span><br><span class="line">    &#125;</span><br><span class="line">    t1.val+=t2.val;</span><br><span class="line">    t1.left=mergeTrees(t1.left,t2.left);</span><br><span class="line">    t1.right=mergeTrees(t1.right,t2.right);</span><br><span class="line">    <span class="keyword">return</span> t1;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="530-二叉搜索树的最小绝对差"><a href="#530-二叉搜索树的最小绝对差" class="headerlink" title="530. 二叉搜索树的最小绝对差"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst/" >530. 二叉搜索树的最小绝对差<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个所有节点为非负值的二叉搜索树，求树中任意两节点的差的绝对值的最小值。</p>
<p><strong>示例 :</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line"></span><br><span class="line">   <span class="number">1</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">3</span></span><br><span class="line">    /</span><br><span class="line">   <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出:</span><br><span class="line"><span class="number">1</span></span><br><span class="line"></span><br><span class="line">解释:</span><br><span class="line">最小绝对差为<span class="number">1</span>，其中 <span class="number">2</span> 和 <span class="number">1</span> 的差的绝对值为 <span class="number">1</span>（或者 <span class="number">2</span> 和 <span class="number">3</span>）。</span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong> 树中至少有2个节点。</p>
<p><strong>解法一</strong></p>
<p>很可惜，这题还WA了一次。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getMinimumDifference</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">int</span> diff=Integer.MAX_VALUE,last=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty() || cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.push(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        <span class="keyword">if</span> (last!=-<span class="number">1</span>) &#123;</span><br><span class="line">            diff=Math.min(diff,Math.abs(last-cur.val));   </span><br><span class="line">        &#125;</span><br><span class="line">        last=cur.val;</span><br><span class="line">        cur=cur.right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> diff;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>递归的方式</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> diff = Integer.MAX_VALUE;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> last = -<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getMinimumDifference</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    inorder(root);</span><br><span class="line">    <span class="keyword">return</span> diff;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">inorder</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    inorder(root.left);</span><br><span class="line">    diff = last==-<span class="number">1</span>?diff:Math.min(diff,Math.abs(last-root.val));</span><br><span class="line">    last = root.val;</span><br><span class="line">    inorder(root.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="501-二叉搜索树中的众数"><a href="#501-二叉搜索树中的众数" class="headerlink" title="501. 二叉搜索树中的众数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-mode-in-binary-search-tree/" >501. 二叉搜索树中的众数<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>简单</strong></p>
<p>给定一个有相同值的二叉搜索树（BST），找出 BST 中的所有众数（出现频率最高的元素）。</p>
<p>假定 BST 有如下定义：</p>
<ul>
<li>  结点左子树中所含结点的值小于等于当前结点的值</li>
<li>  结点右子树中所含结点的值大于等于当前结点的值</li>
<li>  左子树和右子树都是二叉搜索树</li>
</ul>
<p>例如：<br>给定 BST <code>[1,null,2,2]</code>,</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="number">1</span></span><br><span class="line"> \</span><br><span class="line">  <span class="number">2</span></span><br><span class="line"> /</span><br><span class="line"><span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><code>返回[2]</code>.</p>
<p><strong>提示</strong>：如果众数超过1个，不需考虑输出顺序</p>
<p><strong>进阶：</strong>你可以不使用额外的空间吗？（假设由递归产生的隐式调用栈的开销不被计算在内）</p>
<p><strong>解法一</strong></p>
<p>之前忘了记录了，中序遍历统计答案就ok，但是非要严格的O(1)就需要使用Morris遍历（不会</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * type TreeNode struct &#123;</span></span><br><span class="line"><span class="comment"> *     Val int</span></span><br><span class="line"><span class="comment"> *     Left *TreeNode</span></span><br><span class="line"><span class="comment"> *     Right *TreeNode</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findMode</span><span class="params">(root *TreeNode)</span> []<span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span></span><br><span class="line">    <span class="keyword">var</span> prev *TreeNode</span><br><span class="line">    <span class="keyword">var</span> count, max = <span class="number">0</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> res []<span class="keyword">int</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Left)</span><br><span class="line">        <span class="keyword">if</span> prev == <span class="literal">nil</span> || prev.Val == root.Val &#123;</span><br><span class="line">            count++</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            count = <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> count == max &#123;</span><br><span class="line">            res = <span class="built_in">append</span>(res, root.Val)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> count &gt; max &#123;</span><br><span class="line">            res = []<span class="keyword">int</span>&#123;&#125;</span><br><span class="line">            res = <span class="built_in">append</span>(res, root.Val)</span><br><span class="line">            max = count</span><br><span class="line">        &#125;</span><br><span class="line">        prev = root</span><br><span class="line">        dfs(root.Right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br></pre></td></tr></table></figure>

<h2 id="515-在每个树行中找最大值"><a href="#515-在每个树行中找最大值" class="headerlink" title="515. 在每个树行中找最大值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/" >515. 在每个树行中找最大值<i class="fas fa-external-link-alt"></i></a></h2><p>您需要在二叉树的每一行中找到最大的值。</p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">	  <span class="number">1</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">3</span>   <span class="number">2</span></span><br><span class="line">   / \   \  </span><br><span class="line">  <span class="number">5</span>   <span class="number">3</span>   <span class="number">9</span> </span><br><span class="line">输出: [<span class="number">1</span>, <span class="number">3</span>, <span class="number">9</span>]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>娱乐题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">largestValues</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    dfs(root,res,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode node,List&lt;Integer&gt; list,<span class="keyword">int</span> level)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (level&gt;=list.size()) &#123;</span><br><span class="line">        list.add(node.val);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(node.val&gt;list.get(level))&#123;</span><br><span class="line">        list.set(level,node.val);</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(node.left,list,level+<span class="number">1</span>);</span><br><span class="line">    dfs(node.right,list,level+<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="173-二叉搜索树迭代器"><a href="#173-二叉搜索树迭代器" class="headerlink" title="173. 二叉搜索树迭代器"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-search-tree-iterator/" >173. 二叉搜索树迭代器<i class="fas fa-external-link-alt"></i></a></h2><p>实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。</p>
<p>调用 <code>next()</code> 将返回二叉搜索树中的下一个最小的数。</p>
<p> <strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2019/12/25/TXK397rI5hwjG4B.png"
                      alt="leetcode"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">BSTIterator iterator = <span class="keyword">new</span> BSTIterator(root);</span><br><span class="line">iterator.next();    <span class="comment">// 返回 3</span></span><br><span class="line">iterator.next();    <span class="comment">// 返回 7</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 true</span></span><br><span class="line">iterator.next();    <span class="comment">// 返回 9</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 true</span></span><br><span class="line">iterator.next();    <span class="comment">// 返回 15</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 true</span></span><br><span class="line">iterator.next();    <span class="comment">// 返回 20</span></span><br><span class="line">iterator.hasNext(); <span class="comment">// 返回 false</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>next() 和 hasNext() 操作的时间复杂度是 O(1)，并使用 <strong>O(h)</strong> 内存，其中 h 是树的高度。</li>
<li>你可以假设 next() 调用总是有效的，也就是说，当调用 next() 时，BST 中至少存在一个下一个最小的数。 </li>
</ul>
<p><strong>解法一</strong></p>
<p>注意这题空间复杂度要求是<code>O(h)</code> ，并不是憨憨题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">BSTIterator</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    pushLeft(root);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">next</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    TreeNode node=stack.pop();</span><br><span class="line">    <span class="keyword">if</span> (node.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        pushLeft(node.right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> node.val;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">hasNext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> !stack.isEmpty();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pushLeft</span><span class="params">(TreeNode node)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(node!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        stack.add(node);</span><br><span class="line">        node=node.left;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们可以用一个stack存储BST的左链，当取最小值就从stack中直接取，如果取出来的node还有右子树就将右子树的左链也添加进来，是不是有点熟悉？其实就是中序遍历的过程</p>
<h2 id="95-不同的二叉搜索树-II"><a href="#95-不同的二叉搜索树-II" class="headerlink" title="95. 不同的二叉搜索树 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/unique-binary-search-trees-ii/" >95. 不同的二叉搜索树 II<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个整数 n，生成所有由 1 … n 为节点所组成的<strong>二叉搜索树</strong>。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">3</span></span><br><span class="line">输出:</span><br><span class="line">[</span><br><span class="line">  [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">3</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">1</span>],</span><br><span class="line">  [<span class="number">3</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">2</span>],</span><br><span class="line">  [<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>],</span><br><span class="line">  [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">3</span>]</span><br><span class="line">]</span><br><span class="line">解释:</span><br><span class="line">以上的输出对应以下 <span class="number">5</span> 种不同结构的二叉搜索树：</span><br><span class="line"></span><br><span class="line">   <span class="number">1</span>         <span class="number">3</span>     <span class="number">3</span>      <span class="number">2</span>      <span class="number">1</span></span><br><span class="line">    \       /     /      / \      \</span><br><span class="line">     <span class="number">3</span>     <span class="number">2</span>     <span class="number">1</span>      <span class="number">1</span>   <span class="number">3</span>      <span class="number">2</span></span><br><span class="line">    /     /       \                 \</span><br><span class="line">   <span class="number">2</span>     <span class="number">1</span>         <span class="number">2</span>                 <span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span>  List&lt;TreeNode&gt; <span class="title">generateTrees</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(n&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> generateTrees(<span class="number">1</span>,n);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;TreeNode&gt; <span class="title">generateTrees</span><span class="params">(<span class="keyword">int</span> start,<span class="keyword">int</span> end)</span> </span>&#123;</span><br><span class="line">    List&lt;TreeNode&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (start&gt;end) &#123;</span><br><span class="line">        <span class="comment">//null也是一种情况，左右子树为空</span></span><br><span class="line">        res.add(<span class="keyword">null</span>);</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=start;i&lt;=end;i++) &#123;</span><br><span class="line">        List&lt;TreeNode&gt; left=generateTrees(start,i-<span class="number">1</span>);</span><br><span class="line">        List&lt;TreeNode&gt; right=generateTrees(i+<span class="number">1</span>,end);</span><br><span class="line">        <span class="keyword">for</span> (TreeNode l:left) &#123;</span><br><span class="line">            <span class="keyword">for</span> (TreeNode r:right) &#123;</span><br><span class="line">                TreeNode currentNode=<span class="keyword">new</span> TreeNode(i);</span><br><span class="line">                currentNode.left=l;</span><br><span class="line">                currentNode.right=r;</span><br><span class="line">                res.add(currentNode);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>很久之前做过的题，今天又拿出来看看，其实属于分治思路</p>
<h2 id="538-把二叉搜索树转换为累加树"><a href="#538-把二叉搜索树转换为累加树" class="headerlink" title="538. 把二叉搜索树转换为累加树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/convert-bst-to-greater-tree/" >538. 把二叉搜索树转换为累加树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉搜索树（Binary Search Tree），把它转换成为累加树（Greater Tree)，使得每个节点的值是原来的节点值加上所有大于它的节点值之和。</p>
<p><strong>例如：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: 二叉搜索树:</span><br><span class="line">              <span class="number">5</span></span><br><span class="line">            /   \</span><br><span class="line">           <span class="number">2</span>     <span class="number">13</span></span><br><span class="line"></span><br><span class="line">输出: 转换为累加树:</span><br><span class="line">             <span class="number">18</span></span><br><span class="line">            /   \</span><br><span class="line">          <span class="number">20</span>     <span class="number">13</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>这里我想先上一个<strong>错误的解法</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//以下代码纯属娱乐</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">convertBST</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(<span class="number">0</span>);<span class="comment">//这里肯定是错的，null应该直接返回null</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    root.val+= convertBST(root.right).val;</span><br><span class="line">    convertBST(root.left).val+=root.val;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>忽略返回值的部分，乍一看好像是对的😂，其实问题大了，首先是左边的值算的不对，因为是DFS会从最左边开始算，都只加了他的父节点原始的值，而父节点的累加值还没有算出来，其次有些情况是算不出来的比如左子树的某一个右节点你就算不出来</p>
<p><strong>解法二</strong></p>
<p>其实一开始就知道可以直接中序遍历做，只是想玩一些其他的方法，可惜没搞出来😂</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">convertBST</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root.right);</span><br><span class="line">    sum+=root.val;</span><br><span class="line">    root.val=sum;</span><br><span class="line">    dfs(root.left);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里需要注意的就是要翻过来遍历，从大到小，因为它求的是比它大的节点的值</p>
<h2 id="508-出现次数最多的子树元素和"><a href="#508-出现次数最多的子树元素和" class="headerlink" title="508. 出现次数最多的子树元素和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/most-frequent-subtree-sum/" >508. 出现次数最多的子树元素和<i class="fas fa-external-link-alt"></i></a></h2><p>给出二叉树的根，找出出现次数最多的子树元素和。一个结点的子树元素和定义为以该结点为根的二叉树上所有结点的元素之和（包括结点本身）。然后求出出现次数最多的子树元素和。如果有多个元素出现的次数相同，返回所有出现次数最多的元素（不限顺序）。</p>
<p><strong>示例 1</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line"></span><br><span class="line">  <span class="number">5</span></span><br><span class="line"> /  \</span><br><span class="line"><span class="number">2</span>   -<span class="number">3</span></span><br><span class="line">返回 [<span class="number">2</span>, -<span class="number">3</span>, <span class="number">4</span>]，所有的值均只出现一次，以任意顺序返回所有值。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line"></span><br><span class="line">  <span class="number">5</span></span><br><span class="line"> /  \</span><br><span class="line"><span class="number">2</span>   -<span class="number">5</span></span><br><span class="line">返回 [<span class="number">2</span>]，只有 <span class="number">2</span> 出现两次，-<span class="number">5</span> 只出现 <span class="number">1</span> 次。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>左子树和+右子树和，HashMap记录出现的次数，记录最大值然后取出出现次数最多的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> Map&lt;Integer,Integer&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> maxCount=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] findFrequentTreeSum(TreeNode root) &#123;</span><br><span class="line">    <span class="keyword">if</span> (root ==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root);</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    map.keySet().stream().filter(val-&gt;map.get(val)==maxCount).forEach(res::add);</span><br><span class="line">    <span class="keyword">return</span> res.stream().mapToInt(Integer::valueOf).toArray(); <span class="comment">//list转数组的又一个小技巧，单纯的toArray只能转换成Integer[],还需要转</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> value=root.val+dfs(root.right)+dfs(root.left);</span><br><span class="line">    map.put(value,map.getOrDefault(value,<span class="number">0</span>)+<span class="number">1</span>);</span><br><span class="line">    maxCount=Math.max(maxCount,map.get(value));</span><br><span class="line">    <span class="keyword">return</span> value;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>写法是基于Lambda的，函数式写起来真的舒服</p>
<h2 id="606-根据二叉树创建字符串"><a href="#606-根据二叉树创建字符串" class="headerlink" title="606. 根据二叉树创建字符串"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/construct-string-from-binary-tree/" >606. 根据二叉树创建字符串<i class="fas fa-external-link-alt"></i></a></h2><p>你需要采用前序遍历的方式，将一个二叉树转换成一个由括号和整数组成的字符串。</p>
<p>空节点则用一对空括号 “()” 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: 二叉树: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line">       <span class="number">1</span></span><br><span class="line">     /   \</span><br><span class="line">    <span class="number">2</span>     <span class="number">3</span></span><br><span class="line">   /    </span><br><span class="line">  <span class="number">4</span>     </span><br><span class="line"></span><br><span class="line">输出: <span class="string">&quot;1(2(4))(3)&quot;</span></span><br><span class="line"></span><br><span class="line">解释: 原本将是“<span class="number">1</span>(<span class="number">2</span>(<span class="number">4</span>)())(<span class="number">3</span>())”，</span><br><span class="line">在你省略所有不必要的空括号对之后，</span><br><span class="line">它将是“<span class="number">1</span>(<span class="number">2</span>(<span class="number">4</span>))(<span class="number">3</span>)”。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: 二叉树: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">4</span>]</span><br><span class="line">       <span class="number">1</span></span><br><span class="line">     /   \</span><br><span class="line">    <span class="number">2</span>     <span class="number">3</span></span><br><span class="line">     \  </span><br><span class="line">      <span class="number">4</span> </span><br><span class="line"></span><br><span class="line">输出: <span class="string">&quot;1(2()(4))(3)&quot;</span></span><br><span class="line"></span><br><span class="line">解释: 和第一个示例相似，</span><br><span class="line">除了我们不能省略第一个对括号来中断输入和输出之间的一对一映射关系。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">tree2str</span><span class="params">(TreeNode t)</span> </span>&#123;</span><br><span class="line">    StringBuilder s=<span class="keyword">new</span> StringBuilder();</span><br><span class="line">    dfs(t,s);</span><br><span class="line">    <span class="keyword">return</span> s.toString();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode node,StringBuilder s)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    s.append(node.val);</span><br><span class="line">    <span class="keyword">if</span>(node.left==<span class="keyword">null</span> &amp;&amp; node.right==<span class="keyword">null</span>)&#123;<span class="comment">//没有子节点</span></span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    s.append(<span class="string">&quot;(&quot;</span>);</span><br><span class="line">    dfs(node.left,s);</span><br><span class="line">    s.append(<span class="string">&quot;)&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (node.right==<span class="keyword">null</span>) &#123; <span class="comment">//没有右节点</span></span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    s.append(<span class="string">&quot;(&quot;</span>);</span><br><span class="line">    dfs(node.right,s);</span><br><span class="line">    s.append(<span class="string">&quot;)&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>没啥好说的，搞清楚题目意思然后注意递归的几个出口就行了</p>
<h2 id="1315-祖父节点值为偶数的节点和"><a href="#1315-祖父节点值为偶数的节点和" class="headerlink" title="1315. 祖父节点值为偶数的节点和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sum-of-nodes-with-even-valued-grandparent/" >1315. 祖父节点值为偶数的节点和<i class="fas fa-external-link-alt"></i></a></h2><p>给你一棵二叉树，请你返回满足以下条件的所有节点的值之和：</p>
<p>该节点的祖父节点的值为偶数。（一个节点的祖父节点是指该节点的父节点的父节点。）<br>如果不存在祖父节点值为偶数的节点，那么返回 0 。</p>
<p><strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/01/13/CgBK9WOMbNvxJpY.png"
                      alt="1473_ex1.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">2</span>,<span class="number">7</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">9</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">5</span>]</span><br><span class="line">输出：<span class="number">18</span></span><br><span class="line">解释：图中红色节点的祖父节点的值为偶数，蓝色节点为这些红色节点的祖父节点。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>树中节点的数目在 <code>1</code> 到 <code>10^4</code> 之间。</li>
<li>每个节点的值在 <code>1</code> 到 <code>100</code> 之间。</li>
</ul>
<p><strong>解法一</strong></p>
<p>好像是170前一天的双周赛的第3题，还是很直白的题，遍历的时候带上它的father的值和grandfather的值带到下一层，然后判断就可以了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">sumEvenGrandparent</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> dfs(root,-<span class="number">1</span>,-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode node,<span class="keyword">int</span> fa,<span class="keyword">int</span> ga)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span> (fa!=-<span class="number">1</span> &amp;&amp; ga!=-<span class="number">1</span> &amp;&amp; ga%<span class="number">2</span>==<span class="number">0</span>) &#123;</span><br><span class="line">        sum+=node.val;</span><br><span class="line">    &#125;</span><br><span class="line">    sum+=dfs(node.left,node.val,fa);</span><br><span class="line">    sum+=dfs(node.right,node.val,fa);</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<h2 id="1026-节点与其祖先之间的最大差值"><a href="#1026-节点与其祖先之间的最大差值" class="headerlink" title="1026. 节点与其祖先之间的最大差值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-difference-between-node-and-ancestor/" >1026. 节点与其祖先之间的最大差值<i class="fas fa-external-link-alt"></i></a></h2><p>给定二叉树的根节点 <code>root</code>，找出存在于不同节点 <code>A</code> 和 <code>B</code> 之间的最大值 <code>V</code>，其中 <code>V = |A.val - B.val|</code>，且 <code>A</code> 是 <code>B</code> 的祖先。</p>
<p>（如果 A 的任何子节点之一为 B，或者 A 的任何子节点是 B 的祖先，那么我们认为 A 是 B 的祖先）</p>
<p><strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/03/YpF3r9.png"
                      alt="YpF3r9.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">8</span>,<span class="number">3</span>,<span class="number">10</span>,<span class="number">1</span>,<span class="number">6</span>,<span class="keyword">null</span>,<span class="number">14</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">4</span>,<span class="number">7</span>,<span class="number">13</span>]</span><br><span class="line">输出：<span class="number">7</span></span><br><span class="line">解释： </span><br><span class="line">我们有大量的节点与其祖先的差值，其中一些如下：</span><br><span class="line">|<span class="number">8</span> - <span class="number">3</span>| = <span class="number">5</span></span><br><span class="line">|<span class="number">3</span> - <span class="number">7</span>| = <span class="number">4</span></span><br><span class="line">|<span class="number">8</span> - <span class="number">1</span>| = <span class="number">7</span></span><br><span class="line">|<span class="number">10</span> - <span class="number">13</span>| = <span class="number">3</span></span><br><span class="line">在所有可能的差值中，最大值 <span class="number">7</span> 由 |<span class="number">8</span> - <span class="number">1</span>| = <span class="number">7</span> 得出。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li>树中的节点数在 <code>2</code> 到 <code>5000</code> 之间。</li>
<li>每个节点的值介于 <code>0</code> 到 <code>100000</code> 之间。</li>
</ol>
<p><strong>解法一</strong></p>
<p>水题，维护每条路径上的最值，然后统计最大差就行了</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">maxAncestorDiff</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    dfs(root, <span class="number">1</span>&lt;&lt;<span class="number">30</span>, <span class="number">-1</span>&gt;&gt;<span class="number">30</span>, &amp;res)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(root *TreeNode, min, max <span class="keyword">int</span>, res *<span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    min = fmin(min, root.Val)</span><br><span class="line">    max = fmax(max, root.Val)</span><br><span class="line">    *res = fmax(max-min, *res)</span><br><span class="line">    dfs(root.Left, min, max, res)</span><br><span class="line">    dfs(root.Right, min, max, res)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fmin</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">fmax</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &gt; b &#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="1325-删除给定值的叶子节点"><a href="#1325-删除给定值的叶子节点" class="headerlink" title="1325. 删除给定值的叶子节点"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/delete-leaves-with-a-given-value/" >1325. 删除给定值的叶子节点<i class="fas fa-external-link-alt"></i></a></h2><p>给你一棵以 <code>root</code> 为根的二叉树和一个整数 <code>target</code> ，请你删除所有值为 <code>target</code> 的 叶子节点 。</p>
<p>注意，一旦删除值为 <code>target</code> 的叶子节点，它的父节点就可能变成叶子节点；如果新叶子节点的值恰好也是 <code>target</code> ，那么这个节点也应该被删除。</p>
<p>也就是说，你需要重复此过程直到不能继续删除。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/01/28/e7dOxoLNciVa4Uf.png"
                      alt="image.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="number">4</span>], target = <span class="number">2</span></span><br><span class="line">输出：[<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">4</span>]</span><br><span class="line">解释：</span><br><span class="line">上面左边的图中，绿色节点为叶子节点，且它们的值与 target 相同（同为 <span class="number">2</span> ），它们会被删除，得到中间的图。</span><br><span class="line">有一个新的节点变成了叶子节点且它的值与 target 相同，所以将再次进行删除，从而得到最右边的图。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/01/28/aNLo4wQz3C1ZiAf.png"
                      alt="image.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">3</span>,<span class="number">2</span>], target = <span class="number">3</span></span><br><span class="line">输出：[<span class="number">1</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">2</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/01/28/JHBRy7uZDFWLMVT.png"
                      alt="image.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">2</span>], target = <span class="number">2</span></span><br><span class="line">输出：[<span class="number">1</span>]</span><br><span class="line">解释：每一步都删除一个绿色的叶子节点（值为 <span class="number">2</span>）。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= target &lt;= 1000</code></li>
<li>每一棵树最多有 <code>3000</code> 个节点。</li>
<li>每一个节点值的范围是 <code>[1, 1000]</code> 。</li>
</ul>
<p><strong>解法一</strong></p>
<p>某次周赛的第三题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">removeLeafNodes</span><span class="params">(TreeNode root, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> delete(root,target);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">delete</span><span class="params">(TreeNode root,<span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    root.left=delete(root.left,target);</span><br><span class="line">    root.right=delete(root.right,target);</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span> &amp;&amp; root.val==target) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>搞了半天。。。一开始写的时候写的前序遍历的方式，先删除自己然后再去删除左右孩子，然后在如何判断是否有叶子节点上卡了半天，最后写了个for3000的循环过的。。。好菜啊，只要交换一下顺序变成后序遍历的方式，先删除左右子节点，然后再回头删除自己的就可以一直删了。。</p>
<h2 id="1305-两棵二叉搜索树中的所有元素"><a href="#1305-两棵二叉搜索树中的所有元素" class="headerlink" title="1305. 两棵二叉搜索树中的所有元素"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/all-elements-in-two-binary-search-trees/" >1305. 两棵二叉搜索树中的所有元素<i class="fas fa-external-link-alt"></i></a></h2><p>给你 <code>root1</code> 和 <code>root2</code> 这两棵二叉搜索树。</p>
<p>请你返回一个列表，其中包含 <strong>两棵树</strong> 中的所有整数并按 <strong>升序</strong> 排序。.</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/01/31/Hy3MEwa4sRO6jUq.png"
                      alt="image.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root1 = [<span class="number">2</span>,<span class="number">1</span>,<span class="number">4</span>], root2 = [<span class="number">1</span>,<span class="number">0</span>,<span class="number">3</span>]</span><br><span class="line">输出：[<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root1 = [<span class="number">0</span>,-<span class="number">10</span>,<span class="number">10</span>], root2 = [<span class="number">5</span>,<span class="number">1</span>,<span class="number">7</span>,<span class="number">0</span>,<span class="number">2</span>]</span><br><span class="line">输出：[-<span class="number">10</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">7</span>,<span class="number">10</span>]</span><br></pre></td></tr></table></figure>


<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root1 = [], root2 = [<span class="number">5</span>,<span class="number">1</span>,<span class="number">7</span>,<span class="number">0</span>,<span class="number">2</span>]</span><br><span class="line">输出：[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">7</span>]</span><br></pre></td></tr></table></figure>


<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root1 = [<span class="number">0</span>,-<span class="number">10</span>,<span class="number">10</span>], root2 = []</span><br><span class="line">输出：[-<span class="number">10</span>,<span class="number">0</span>,<span class="number">10</span>]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>某次周赛的题，大水题，白板回忆写出了中序的非递归haha，感觉忘不了了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">getAllElements</span><span class="params">(TreeNode root1, TreeNode root2)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//return megerList(inorder(root1),0,inorder(root2),0);</span></span><br><span class="line">    <span class="keyword">return</span> megerList(inorder(root1),inorder(root2));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">inorder</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty() || cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            stack.add(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        res.add(cur.val);</span><br><span class="line">        cur=cur.right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">megerList</span><span class="params">(List&lt;Integer&gt; list1,List&lt;Integer&gt; list2)</span></span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span> index1=<span class="number">0</span>,index2=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(index1&lt;list1.size() &amp;&amp; index2&lt;list2.size())&#123;</span><br><span class="line">        res.add(list1.get(index1)&lt;list2.get(index2)?list1.get(index1++):list2.get(index2++));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(index1&lt;list1.size())&#123;</span><br><span class="line">        res.add(list1.get(index1++));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(index2&lt;list2.size())&#123;</span><br><span class="line">        res.add(list2.get(index2++));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//递归的TLE了 42/48,不停的创建list太耗时了</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">megerList</span><span class="params">(List&lt;Integer&gt; list1,<span class="keyword">int</span> index1,List&lt;Integer&gt; list2,<span class="keyword">int</span> index2)</span></span>&#123;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">if</span> (index1==list1.size()) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=index2;i&lt;list2.size();i++) &#123;</span><br><span class="line">            res.add(list2.get(i));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (index2==list2.size()) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=index1;i&lt;list1.size();i++) &#123;</span><br><span class="line">            res.add(list1.get(i));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (list1.get(index1)&lt;list2.get(index2)) &#123;</span><br><span class="line">        res.add(list1.get(index1));</span><br><span class="line">        res.addAll(megerList(list1,index1+<span class="number">1</span>,list2,index2));</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        res.add(list2.get(index2));</span><br><span class="line">        res.addAll(megerList(list1,index1,list2,index2+<span class="number">1</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1339-分裂二叉树的最大乘积"><a href="#1339-分裂二叉树的最大乘积" class="headerlink" title="1339. 分裂二叉树的最大乘积"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-product-of-splitted-binary-tree/" >1339. 分裂二叉树的最大乘积<i class="fas fa-external-link-alt"></i></a></h2><p>给你一棵二叉树，它的根为 root 。请你删除 1 条边，使二叉树分裂成两棵子树，且它们子树和的乘积尽可能大。</p>
<p>由于答案可能会很大，请你将结果对 10^9 + 7 取模后再返回。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/02/02/HT93vAj7gcXwY8U.png"
                      alt="image.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]</span><br><span class="line">输出：<span class="number">110</span></span><br><span class="line">解释：删除红色的边，得到 <span class="number">2</span> 棵子树，和分别为 <span class="number">11</span> 和 <span class="number">10</span> 。它们的乘积是 <span class="number">110</span> （<span class="number">11</span>*<span class="number">10</span>）</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://i.loli.net/2020/02/02/Fit7Xl2jkzCZyhV.png"
                      alt="image.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">5</span>,<span class="number">6</span>]</span><br><span class="line">输出：<span class="number">90</span></span><br><span class="line">解释：移除红色的边，得到 <span class="number">2</span> 棵子树，和分别是 <span class="number">15</span> 和 <span class="number">6</span> 。它们的乘积为 <span class="number">90</span> （<span class="number">15</span>*<span class="number">6</span>）</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>174周赛的第三题，当时比赛TLE了。。写了个很蠢的算法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">long</span> mod=<span class="number">1000000007</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxProduct</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    Stack&lt;TreeNode&gt; stack=<span class="keyword">new</span> Stack&lt;&gt;();</span><br><span class="line">    TreeNode cur=root;</span><br><span class="line">    <span class="keyword">long</span> sumAll=sum(root);</span><br><span class="line">    <span class="keyword">while</span>(!stack.isEmpty() || cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        TreeNode temp=<span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">long</span> s=<span class="number">0L</span>;</span><br><span class="line">        <span class="keyword">while</span>(cur!=<span class="keyword">null</span>)&#123;</span><br><span class="line">            temp=cur.left;</span><br><span class="line">            cur.left=<span class="keyword">null</span>;</span><br><span class="line">            <span class="keyword">long</span> r=sum(root);</span><br><span class="line">            s=r*(sumAll-r);</span><br><span class="line">            max=Math.max(s,max);</span><br><span class="line">            cur.left=temp;</span><br><span class="line">            stack.add(cur);</span><br><span class="line">            cur=cur.left;</span><br><span class="line">        &#125;</span><br><span class="line">        cur=stack.pop();</span><br><span class="line">        temp=cur.right;</span><br><span class="line">        cur.right=<span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">long</span> r=sum(root);</span><br><span class="line">        s=r*(sumAll-r);</span><br><span class="line">        max=Math.max(s,max);</span><br><span class="line">        cur.right=temp;</span><br><span class="line">        cur=cur.right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int</span>)(max%mod);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">long</span> max=-<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">long</span> <span class="title">sum</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root.val+sum(root.left)+sum(root.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我居然真的去删除节点去了。。。导致后面都没办法对sum做记忆化，太菜了啊</p>
<p><strong>解法二</strong></p>
<p>能AC但是效率感人</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">long</span> mod=<span class="number">1000000007</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">long</span> sumAll=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">long</span> max=-<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxProduct</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    sumAll=sum(root);</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int</span>)(max%mod);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">long</span> temp=sum(root);</span><br><span class="line">    max=Math.max(max,temp*(sumAll-temp));</span><br><span class="line">    dfs(root.left);</span><br><span class="line">    dfs(root.right);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> HashMap&lt;String,Long&gt; cache=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">long</span> <span class="title">sum</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (cache.containsKey(root.toString())) &#123;</span><br><span class="line">        <span class="keyword">return</span> cache.get(root.toString());</span><br><span class="line">    &#125;</span><br><span class="line">    cache.put(root.toString(),root.val+sum(root.left)+sum(root.right));</span><br><span class="line">    <span class="keyword">return</span> cache.get(root.toString());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法三</strong></p>
<p>标准<code>O(N)</code>的解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">long</span> mod=<span class="number">1000000007</span>;    </span><br><span class="line"></span><br><span class="line">List&lt;Long&gt; sum=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="comment">//标准解法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxProduct</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">long</span> max=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">long</span> sumAll=dfs(root);</span><br><span class="line">    <span class="keyword">for</span> (Long s:sum) &#123;</span><br><span class="line">        max=Math.max(max,s*(sumAll-s));    </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int</span>)(max%mod);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">long</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    sum.add(root.val+dfs(root.left)+dfs(root.right));</span><br><span class="line">    <span class="keyword">return</span> sum.get(sum.size()-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在dfs的过程中将子树的sum存起来，然后直接遍历list，求 <code>max(s*(sumAll-s))</code>就ok</p>
<blockquote>
<p>这里最开始被大数据也卡了一会儿，不知道啥时候取模，其实这里题目没有那么难，相乘的结果并不会溢出Long，如果要是溢出Long的话可能就要用什么带模快速乘了</p>
</blockquote>
<h2 id="297-二叉树的序列化与反序列化"><a href="#297-二叉树的序列化与反序列化" class="headerlink" title="297. 二叉树的序列化与反序列化"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/" >297. 二叉树的序列化与反序列化<i class="fas fa-external-link-alt"></i></a></h2><p>序列化是将一个数据结构或者对象转换为连续的比特位的操作，进而可以将转换后的数据存储在一个文件或者内存中，同时也可以通过网络传输到另一个计算机环境，采取相反方式重构得到原数据。</p>
<p>请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑，你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。</p>
<p><strong>示例:</strong> </p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">你可以将以下二叉树：</span><br><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">3</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">4</span>   <span class="number">5</span></span><br><span class="line"></span><br><span class="line">序列化为 <span class="string">&quot;[1,2,3,null,null,4,5]&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>提示:</strong> 这与 LeetCode 目前使用的方式一致，详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式，你也可以采用其他的方法解决这个问题。</p>
<p><strong>说明:</strong> 不要使用类的成员 / 全局 / 静态变量来存储状态，你的序列化和反序列化算法应该是无状态的。</p>
<p><strong>解法一</strong></p>
<p>层序遍历非递归的方式</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//层序遍历的方式</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">serialize</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//BFS</span></span><br><span class="line">    StringBuilder sb=<span class="keyword">new</span> StringBuilder();</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        TreeNode cur=queue.poll();</span><br><span class="line">        <span class="keyword">if</span> (cur!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            sb.append(cur.val+<span class="string">&quot;,&quot;</span>);</span><br><span class="line">            queue.add(cur.left);</span><br><span class="line">            queue.add(cur.right);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            sb.append(<span class="string">&quot;null,&quot;</span>); <span class="comment">//会多很多null,不过影响不大</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sb.toString();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//按照题目意思写代码就ok</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">deserialize</span><span class="params">(String data)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="string">&quot;&quot;</span>.equals(data)) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    String[] treeData=data.split(<span class="string">&quot;,&quot;</span>);</span><br><span class="line">    <span class="keyword">int</span> index=<span class="number">0</span>;</span><br><span class="line">    TreeNode root=node(treeData[index]);</span><br><span class="line">    Queue&lt;TreeNode&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    queue.add(root);</span><br><span class="line">    <span class="keyword">while</span>(!queue.isEmpty())&#123;</span><br><span class="line">        TreeNode cur=queue.poll();</span><br><span class="line">        cur.left=node(treeData[++index]);</span><br><span class="line">        <span class="keyword">if</span> (cur.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            queue.add(cur.left);</span><br><span class="line">        &#125;</span><br><span class="line">        cur.right=node(treeData[++index]);</span><br><span class="line">        <span class="keyword">if</span> (cur.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">            queue.add(cur.right);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">node</span><span class="params">(String str)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="string">&quot;null&quot;</span>.equals(str)) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(Integer.valueOf(str));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>前序遍历递归方式，我们将序列化的结果存在一个<code>queue</code>中，然后从头开始取，因为是前序遍历，所以整体结构肯定是<code>【root,root.left,root.right】</code> </p>
<p>反序列化关键就是如何区分左右子树，仅仅依靠一个前序遍历是无法重建二叉树的，所以我们可以做一些小手段，在序列化节点为空的时候加入<code>null</code>字符，这样左右节点就会被连续的两个<code>[null,null]</code>分隔开，方便重建</p>
<blockquote>
<p>eg.  示例一：  1,2,null,null,3,4,null,null,5,null,null</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">node</span><span class="params">(String str)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="string">&quot;null&quot;</span>.equals(str)) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(Integer.valueOf(str));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">serialize</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;null&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root.val+<span class="string">&quot;,&quot;</span>+serialize(root.left)+<span class="string">&quot;,&quot;</span>+serialize(root.right);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">deserialize</span><span class="params">(String data)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="string">&quot;&quot;</span>.equals(data)) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    String[] dataTree=data.split(<span class="string">&quot;,&quot;</span>);</span><br><span class="line">    Queue&lt;String&gt; queue=<span class="keyword">new</span> LinkedList&lt;&gt;(Arrays.asList(dataTree));</span><br><span class="line">    <span class="keyword">return</span> deserialize(queue);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">deserialize</span><span class="params">(Queue&lt;String&gt; queue)</span></span>&#123;</span><br><span class="line">    String val=queue.poll();</span><br><span class="line">    <span class="keyword">if</span> (<span class="string">&quot;null&quot;</span>.equals(val)) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode root=node(val);</span><br><span class="line">    root.left=deserialize(queue);</span><br><span class="line">    root.right=deserialize(queue);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法三</strong></p>
<p>补充一个go的写法，和解法二的思路是一样的</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">type</span> Codec <span class="keyword">struct</span> &#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Constructor</span><span class="params">()</span> <span class="title">Codec</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> Codec&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Serializes a tree to a single string.</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Codec)</span> <span class="title">serialize</span><span class="params">(root *TreeNode)</span> <span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;nil&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> strconv.Itoa(root.Val) + <span class="string">&quot;,&quot;</span> + this.serialize(root.Left) + <span class="string">&quot;,&quot;</span> + this.serialize(root.Right)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Deserializes your encoded data to tree.</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Codec)</span> <span class="title">deserialize</span><span class="params">(data <span class="keyword">string</span>)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    queue := strings.Split(data, <span class="string">&quot;,&quot;</span>)</span><br><span class="line">    <span class="keyword">return</span> this.des(&amp;queue)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Codec)</span> <span class="title">des</span><span class="params">(queue *[]<span class="keyword">string</span>)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(*queue) == <span class="number">0</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    cur := (*queue)[<span class="number">0</span>]</span><br><span class="line">    *queue = (*queue)[<span class="number">1</span>:]</span><br><span class="line">    <span class="keyword">if</span> cur == <span class="string">&quot;nil&quot;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    val, _ := strconv.Atoi(cur)</span><br><span class="line">    root := &amp;TreeNode&#123;Val: val&#125;</span><br><span class="line">    root.Left = this.des(queue)</span><br><span class="line">    root.Right = this.des(queue)</span><br><span class="line">    <span class="keyword">return</span> root</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="449-序列化和反序列化二叉搜索树"><a href="#449-序列化和反序列化二叉搜索树" class="headerlink" title="449. 序列化和反序列化二叉搜索树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/serialize-and-deserialize-bst/" >449. 序列化和反序列化二叉搜索树<i class="fas fa-external-link-alt"></i></a></h2><p>序列化是将数据结构或对象转换为一系列位的过程，以便它可以存储在文件或内存缓冲区中，或通过网络连接链路传输，以便稍后在同一个或另一个计算机环境中重建。</p>
<p>设计一个算法来序列化和反序列化二叉搜索树。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串，并且可以将该字符串反序列化为最初的二叉搜索树。</p>
<p>编码的字符串应尽可能紧凑。</p>
<p><strong>注意：</strong> 不要使用类成员/全局/静态变量来存储状态。 你的序列化和反序列化算法应该是无状态的。</p>
<p><strong>解法一</strong></p>
<p>题目说 <code>编码的字符串应尽可能紧凑</code>，所以直接把上面297的搬过来其实不太好，因为会有很多null字符，并且也没有用到题目二<code>bst</code>的条件，<code>bst</code>只需要知道一个前序或者后序就可以还原整棵树，题目就变成了根据<code>前序/后序</code>和<code>中序</code>还原二叉树</p>
<p><code>golang</code>新手，用<code>golang</code>写了一发，感觉写复杂了（官方解法中还有更加激进的压缩编码的方式，感觉有点偏了）</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="keyword">type</span> Codec <span class="keyword">struct</span> &#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Constructor</span><span class="params">()</span> <span class="title">Codec</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> Codec&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Serializes a tree to a single string.</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Codec)</span> <span class="title">serialize</span><span class="params">(root *TreeNode)</span> <span class="title">string</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> queue []<span class="keyword">string</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        queue = <span class="built_in">append</span>(queue, strconv.Itoa(root.Val))</span><br><span class="line">        dfs(root.Left)</span><br><span class="line">        dfs(root.Right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> strings.Join(queue, <span class="string">&quot;,&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Deserializes your encoded data to tree.</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Codec)</span> <span class="title">deserialize</span><span class="params">(data <span class="keyword">string</span>)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> data == <span class="string">&quot;&quot;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//fmt.Println(data)</span></span><br><span class="line">    queue := strings.Split(data, <span class="string">&quot;,&quot;</span>)</span><br><span class="line">    inOrder := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="built_in">len</span>(queue))</span><br><span class="line">    <span class="keyword">for</span> i, v := <span class="keyword">range</span> queue &#123;</span><br><span class="line">        inOrder[i], _ = strconv.Atoi(v)</span><br><span class="line">    &#125;</span><br><span class="line">    preOrder := <span class="built_in">make</span>([]<span class="keyword">int</span>, <span class="built_in">len</span>(inOrder))</span><br><span class="line">    <span class="built_in">copy</span>(preOrder, inOrder)</span><br><span class="line">    sort.Ints(inOrder)</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(preOrder, inOrder []<span class="keyword">int</span>)</span> *<span class="title">TreeNode</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(preOrder, inOrder []<span class="keyword">int</span>)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(inOrder) == <span class="number">0</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">        &#125;</span><br><span class="line">        root := &amp;TreeNode&#123;Val: preOrder[<span class="number">0</span>]&#125;</span><br><span class="line">        rootIdx := <span class="number">0</span></span><br><span class="line">        <span class="keyword">for</span> i, v := <span class="keyword">range</span> inOrder &#123;</span><br><span class="line">            <span class="keyword">if</span> v == preOrder[<span class="number">0</span>] &#123;</span><br><span class="line">                rootIdx = i</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        root.Left = dfs(preOrder[<span class="number">1</span>:rootIdx+<span class="number">1</span>], inOrder[:rootIdx])</span><br><span class="line">        root.Right = dfs(preOrder[rootIdx+<span class="number">1</span>:], inOrder[rootIdx+<span class="number">1</span>:])</span><br><span class="line">        <span class="keyword">return</span> root</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(preOrder, inOrder)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h2 id="面试题33-二叉搜索树的后序遍历序列"><a href="#面试题33-二叉搜索树的后序遍历序列" class="headerlink" title="面试题33. 二叉搜索树的后序遍历序列"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/" >面试题33. 二叉搜索树的后序遍历序列<i class="fas fa-external-link-alt"></i></a></h2><p>输入一个整数数组，判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true，否则返回 false。假设输入的数组的任意两个数字都互不相同。</p>
<p>参考以下这颗二叉搜索树：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">6</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">3</span></span><br></pre></td></tr></table></figure>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">6</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">5</span>]</span><br><span class="line">输出: <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">6</span>,<span class="number">5</span>]</span><br><span class="line">输出: <span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>数组长度 &lt;= 1000</code></li>
</ol>
<p><strong>解法一</strong></p>
<p>核心在于意识到最后一个节点是根节点</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">verifyPostorder</span><span class="params">(<span class="keyword">int</span>[] postorder)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(postorder==<span class="keyword">null</span> || postorder.length&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">return</span> verify(postorder,<span class="number">0</span>,postorder.length-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">verify</span><span class="params">(<span class="keyword">int</span>[] postorder,<span class="keyword">int</span> left,<span class="keyword">int</span> right)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(left&gt;=right) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">int</span> root=postorder[right];</span><br><span class="line">    <span class="comment">//WA点,这里要设置成left-1防止没有左子树的情况,比如5 4 3 2 1</span></span><br><span class="line">    <span class="comment">//这样可以跳过第二个循环并且不用递归验证左子树</span></span><br><span class="line">    <span class="keyword">int</span> index=left-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=right-<span class="number">1</span>;i&gt;=left;i--)&#123; <span class="comment">//从后往前找第一个小于root</span></span><br><span class="line">        <span class="keyword">if</span>(postorder[i]&lt;root)&#123;</span><br><span class="line">            index=i; <span class="comment">//找到第一个小于root的,作为左子树的根</span></span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//判断左子树是否都是小于root的</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=index;i&gt;=left;i--)&#123;</span><br><span class="line">        <span class="keyword">if</span>(postorder[i]&gt;root)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//递归验证左右子树</span></span><br><span class="line">    <span class="keyword">return</span> verify(postorder,left,index) &amp;&amp; verify(postorder,index+<span class="number">1</span>,right-<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题WA了3发，前两发是代码逻辑的问题，想简化代码，结果把自己带坑里面去了，最后一次是因为一个变量设置的问题，代码中已经注释</p>
<p><strong>UPDATE: 2020.7.14</strong></p>
<p>重写了下，这样写就不会有奇怪的WA点了，还是要多注意细节和边界</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">verifyPostorder</span><span class="params">(post []<span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">return</span> dfs(post, <span class="number">0</span>, <span class="built_in">len</span>(post)<span class="number">-1</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(post[] <span class="keyword">int</span>, left <span class="keyword">int</span>, right <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> left&gt;=right&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> p = right<span class="number">-1</span></span><br><span class="line">    <span class="keyword">for</span> p &gt;= left &amp;&amp; post[p] &gt; post[right]&#123;</span><br><span class="line">        p--</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i := p; i &gt;= left; i--&#123;</span><br><span class="line">        <span class="keyword">if</span> post[i] &gt; post[right]&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(post, left, p) &amp;&amp; dfs(post, p+<span class="number">1</span>,right<span class="number">-1</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>单调栈的解法，放在<a href="http://imlgw.top/2019/10/01/leetcode-zhan-dui-lie/#%E9%9D%A2%E8%AF%95%E9%A2%9833-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97">单调栈专题</a>中</p>
<h2 id="654-最大二叉树"><a href="#654-最大二叉树" class="headerlink" title="654. 最大二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-binary-tree/" >654. 最大二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下：</p>
<ol>
<li>二叉树的根是数组中的最大元素。</li>
<li>左子树是通过数组中最大值左边部分构造出的最大二叉树。</li>
<li>右子树是通过数组中最大值右边部分构造出的最大二叉树。</li>
</ol>
<p>通过给定的数组构建最大二叉树，并且输出这个树的根节点。</p>
<p><strong>示例 ：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">6</span>,<span class="number">0</span>,<span class="number">5</span>]</span><br><span class="line">输出：返回下面这棵树的根节点：</span><br><span class="line">	  <span class="number">6</span></span><br><span class="line">	/   \</span><br><span class="line">   <span class="number">3</span>     <span class="number">5</span></span><br><span class="line">    \    / </span><br><span class="line">     <span class="number">2</span>  <span class="number">0</span>   </span><br><span class="line">       \</span><br><span class="line">        <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li>给定的数组的大小在 [1, 1000] 之间。</li>
</ol>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//不做预处理,直接搜索2ms,我这个50ms+.....懒得改的就当练手了</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">constructMaximumBinaryTree</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> n=nums.length;</span><br><span class="line">    <span class="keyword">int</span>[][] max=<span class="keyword">new</span> <span class="keyword">int</span>[n][n];</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">        max[i][i]=i;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> j=i+<span class="number">1</span>;j&lt;n;j++)&#123;</span><br><span class="line">            max[i][j]=nums[j]&gt;nums[max[i][j-<span class="number">1</span>]]?j:max[i][j-<span class="number">1</span>];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(nums,<span class="number">0</span>,n-<span class="number">1</span>,max);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">dfs</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> left,<span class="keyword">int</span> right,<span class="keyword">int</span>[][] max)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(left&gt;right) <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">int</span> maxIdx=max[left][right];</span><br><span class="line">    TreeNode root=<span class="keyword">new</span> TreeNode(nums[maxIdx]);</span><br><span class="line">    root.left=dfs(nums,left,maxIdx-<span class="number">1</span>,max);</span><br><span class="line">    root.right=dfs(nums,maxIdx+<span class="number">1</span>,right,max);</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>慢的主要原因是构建这个树的话大概只会查询logN次（树高度）最大值，而每层查询的复杂度和为N，所以整体的复杂度其实只要O(NlogN)，除非数组完全有序，这样每次分割都及其不均匀，数的高度为N时间复杂度才会到N^2，而我这个就直接是N^2了hhhhh，太菜了，预处理的思想是好的，但是还是要看具体的题目，这里其实很多的区间值都用不上（除非搞线段树🤣</p>
</blockquote>
<p><strong>解法二</strong></p>
<p>这题也可以用单调栈做，明天写，这题还有个2，明天一起做了</p>
<h2 id="998-最大二叉树-II"><a href="#998-最大二叉树-II" class="headerlink" title="998. 最大二叉树 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-binary-tree-ii/" >998. 最大二叉树 II<i class="fas fa-external-link-alt"></i></a></h2><p>题目描述很辣鸡，简单来说就是在<code>最大二叉树A</code>的右边插入一个val，仍然是最大二叉树</p>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">insertIntoMaxTree</span><span class="params">(TreeNode root, <span class="keyword">int</span> val)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(val);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root.val&gt;val)&#123;</span><br><span class="line">        root.right=insertIntoMaxTree(root.right,val);    </span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    TreeNode newRoot=<span class="keyword">new</span> TreeNode(val);</span><br><span class="line">    newRoot.left=root;</span><br><span class="line">    <span class="keyword">return</span> newRoot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="652-寻找重复的子树"><a href="#652-寻找重复的子树" class="headerlink" title="652. 寻找重复的子树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-duplicate-subtrees/" >652. 寻找重复的子树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一棵二叉树，返回所有重复的子树。对于同一类的重复子树，你只需要返回其中任意<strong>一棵</strong>的根结点即可。</p>
<p>两棵树重复是指它们具有相同的结构以及相同的结点值。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">3</span></span><br><span class="line"> /   / \</span><br><span class="line"><span class="number">4</span>   <span class="number">2</span>   <span class="number">4</span></span><br><span class="line">   /</span><br><span class="line">  <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p>下面是两个重复的子树：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">2</span></span><br><span class="line"> /</span><br><span class="line"><span class="number">4</span></span><br></pre></td></tr></table></figure>

<p>和</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">4</span></span><br></pre></td></tr></table></figure>

<p>因此，你需要以列表的形式返回上述重复子树的根结点。</p>
<p><strong>解法一</strong></p>
<p>做了忘了加上了，序列化子树，用哈希表判重就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">HashMap&lt;String,Integer&gt; map=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line">List&lt;TreeNode&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;TreeNode&gt; <span class="title">findDuplicateSubtrees</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="comment">//return &quot;#null&quot;;</span></span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;null&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//String key=&quot;#&quot;+root.val+dfs(root.left)+dfs(root.right);</span></span><br><span class="line">    String key=root.val+dfs(root.left)+dfs(root.right);</span><br><span class="line">    <span class="keyword">int</span> count=map.getOrDefault(key,<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span>(count==<span class="number">1</span>)&#123;</span><br><span class="line">        res.add(root);</span><br><span class="line">    &#125;</span><br><span class="line">    map.put(key,count+<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">return</span> key;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>这题少了case，不加分隔符也能A，我以为会卡这个，试了下结果没卡，100积分到手 ==&gt;  <a class="link"   target="_blank" rel="noopener" href="https://github.com/LeetCode-Feedback/LeetCode-Feedback/issues/284" >issue<i class="fas fa-external-link-alt"></i></a> </p>
</blockquote>
<h2 id="653-两数之和-IV-输入-BST"><a href="#653-两数之和-IV-输入-BST" class="headerlink" title="653. 两数之和 IV - 输入 BST"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst/" >653. 两数之和 IV - 输入 BST<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉搜索树和一个目标结果，如果 BST 中存在两个元素且它们的和等于给定的目标结果，则返回 true。</p>
<p><strong>案例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">3</span>   <span class="number">6</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">2</span>   <span class="number">4</span>   <span class="number">7</span></span><br><span class="line"></span><br><span class="line">Target = <span class="number">9</span></span><br><span class="line"></span><br><span class="line">输出: True</span><br></pre></td></tr></table></figure>

<p><strong>案例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">3</span>   <span class="number">6</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">2</span>   <span class="number">4</span>   <span class="number">7</span></span><br><span class="line"></span><br><span class="line">Target = <span class="number">28</span></span><br><span class="line"></span><br><span class="line">输出: False</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>开始还想着在logN的解法，发现好像搞不了，而且这是个easy题，所以肯定就是直接中序+双指针了</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findTarget</span><span class="params">(root *TreeNode, k <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> inorder []<span class="keyword">int</span></span><br><span class="line">    dfs(root, &amp;inorder)</span><br><span class="line">    i, j := <span class="number">0</span>, <span class="built_in">len</span>(inorder)<span class="number">-1</span></span><br><span class="line">    <span class="keyword">for</span> i &lt; j &#123;</span><br><span class="line">        <span class="keyword">if</span> inorder[i]+inorder[j] &lt; k &#123;</span><br><span class="line">            i++</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> inorder[i]+inorder[j] &gt; k &#123;</span><br><span class="line">            j--</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">dfs</span><span class="params">(root *TreeNode, inorder *[]<span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root.Left, inorder)</span><br><span class="line">    *inorder = <span class="built_in">append</span>(*inorder, root.Val)</span><br><span class="line">    dfs(root.Right, inorder)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="872-叶子相似的树"><a href="#872-叶子相似的树" class="headerlink" title="872. 叶子相似的树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/leaf-similar-trees/" >872. 叶子相似的树<i class="fas fa-external-link-alt"></i></a></h2><p>请考虑一颗二叉树上所有的叶子，这些叶子的值按从左到右的顺序排列形成一个 <em>叶值序列</em> 。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/14/YDcL28.png"
                      alt="YDcL28.png"
                ></p>
<p>举个例子，如上图所示，给定一颗叶值序列为 <code>(6, 7, 4, 9, 8)</code> 的树。</p>
<p>如果有两颗二叉树的叶值序列是相同，那么我们就认为它们是 <em>叶相似</em> 的。</p>
<p>如果给定的两个头结点分别为 <code>root1</code> 和 <code>root2</code> 的树是叶相似的，则返回 <code>true</code>；否则返回 <code>false</code> 。</p>
<p><strong>提示：</strong></p>
<ul>
<li>给定的两颗树可能会有 <code>1</code> 到 <code>200</code> 个结点。</li>
<li>给定的两颗树上的值介于 <code>0</code> 到 <code>200</code> 之间。</li>
</ul>
<p><strong>解法一</strong></p>
<p>换成<code>StringBuilder</code>可能会快一点</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//没啥好说的</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">leafSimilar</span><span class="params">(TreeNode root1, TreeNode root2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root1==<span class="keyword">null</span> || root2==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">return</span> dfs(root1).equals(dfs(root2));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;#&quot;</span>+root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dfs(root.left)+dfs(root.right);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>当时看到这题就着会不会又有case遗漏，比如不加分隔符什么的，结果看到github已经有人先手提交了</p>
</blockquote>
<h2 id="5398-统计二叉树中好节点的数目"><a href="#5398-统计二叉树中好节点的数目" class="headerlink" title="5398. 统计二叉树中好节点的数目"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/count-good-nodes-in-binary-tree/" >5398. 统计二叉树中好节点的数目<i class="fas fa-external-link-alt"></i></a></h2><p>给你一棵根为 <code>root</code> 的二叉树，请你返回二叉树中好节点的数目。</p>
<p>「好节点」X 定义为：从根到该节点 X 所经过的节点中，没有任何节点的值大于 X 的值。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/17/YREc7j.png"
                      alt="YREc7j.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">3</span>,<span class="number">1</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="number">5</span>]</span><br><span class="line">输出：<span class="number">4</span></span><br><span class="line">解释：图中蓝色节点为好节点。</span><br><span class="line">根节点 (<span class="number">3</span>) 永远是个好节点。</span><br><span class="line">节点 <span class="number">4</span> -&gt; (<span class="number">3</span>,<span class="number">4</span>) 是路径中的最大值。</span><br><span class="line">节点 <span class="number">5</span> -&gt; (<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>) 是路径中的最大值。</span><br><span class="line">节点 <span class="number">3</span> -&gt; (<span class="number">3</span>,<span class="number">1</span>,<span class="number">3</span>) 是路径中的最大值。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/17/YREukR.png"
                      alt="YREukR.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">3</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">4</span>,<span class="number">2</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：节点 <span class="number">2</span> -&gt; (<span class="number">3</span>, <span class="number">3</span>, <span class="number">2</span>) 不是好节点，因为 <span class="string">&quot;3&quot;</span> 比它大。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：根节点是好节点。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>二叉树中节点数目范围是 <code>[1, 10^5]</code> 。</li>
<li>每个节点权值的范围是 <code>[-10^4, 10^4]</code> 。</li>
</ul>
<p><strong>解法一</strong></p>
<p>26th双周赛的t3，水题</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">goodNodes</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    dfs(root,root.val);</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(TreeNode root,<span class="keyword">int</span> max)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(max&lt;=root.val)&#123;</span><br><span class="line">        count++;</span><br><span class="line">        max=root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root.left,max);</span><br><span class="line">    dfs(root.right,max);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="669-修剪二叉搜索树"><a href="#669-修剪二叉搜索树" class="headerlink" title="669. 修剪二叉搜索树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/trim-a-binary-search-tree/" >669. 修剪二叉搜索树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉搜索树，同时给定最小边界<code>L</code> 和最大边界 <code>R</code>。通过修剪二叉搜索树，使得所有节点的值在<code>[L, R]</code>中 (R&gt;=L) 。你可能需要改变树的根节点，所以结果应当返回修剪好的二叉搜索树的新的根节点。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    1</span><br><span class="line">   / \</span><br><span class="line">  0   2</span><br><span class="line"></span><br><span class="line">  L = 1</span><br><span class="line">  R = 2</span><br><span class="line"></span><br><span class="line">输出: </span><br><span class="line">    1</span><br><span class="line">      \</span><br><span class="line">       2</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">    <span class="number">3</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">0</span>   <span class="number">4</span></span><br><span class="line">   \</span><br><span class="line">    <span class="number">2</span></span><br><span class="line">   /</span><br><span class="line">  <span class="number">1</span></span><br><span class="line"></span><br><span class="line">  L = <span class="number">1</span></span><br><span class="line">  R = <span class="number">3</span></span><br><span class="line"></span><br><span class="line">输出: </span><br><span class="line">      <span class="number">3</span></span><br><span class="line">     / </span><br><span class="line">   <span class="number">2</span>   </span><br><span class="line">  /</span><br><span class="line"> <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>没啥好说的，递归后序遍历就完事了，树的题还是挺套路的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">trimBST</span><span class="params">(TreeNode root, <span class="keyword">int</span> L, <span class="keyword">int</span> R)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> root;</span><br><span class="line">    &#125;</span><br><span class="line">    root.left=trimBST(root.left,L,R);</span><br><span class="line">    root.right=trimBST(root.right,L,R);</span><br><span class="line">    <span class="comment">//root.val&lt;L,左子树全部小于L</span></span><br><span class="line">    <span class="keyword">if</span>(root.val&lt;L)&#123;</span><br><span class="line">        <span class="keyword">return</span> root.right;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root.val&gt;R)&#123;</span><br><span class="line">        <span class="keyword">return</span> root.left;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="814-二叉树剪枝"><a href="#814-二叉树剪枝" class="headerlink" title="814. 二叉树剪枝"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-pruning/" >814. 二叉树剪枝<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给定二叉树根结点 <code>root</code> ，此外树的每个结点的值要么是 0，要么是 1。</p>
<p>返回移除了所有不包含 1 的子树的原二叉树。</p>
<p>( 节点 X 的子树为 X 本身，以及所有 X 的后代。)</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">示例<span class="number">1</span>:</span><br><span class="line">输入: [<span class="number">1</span>,null,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出: [<span class="number">1</span>,null,<span class="number">0</span>,null,<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line">解释: </span><br><span class="line">只有红色节点满足条件“所有不包含 <span class="number">1</span> 的子树”。</span><br><span class="line">右图为返回的答案。</span><br></pre></td></tr></table></figure>

<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">示例<span class="number">2</span>:</span><br><span class="line">输入: [<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出: [<span class="number">1</span>,null,<span class="number">1</span>,null,<span class="number">1</span>]</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">示例<span class="number">3</span>:</span><br><span class="line">输入: [<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>]</span><br><span class="line">输出: [<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,null,<span class="number">1</span>]</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<ul>
<li>  给定的二叉树最多有 <code>100</code> 个节点。</li>
<li>  每个节点的值只会为 <code>0</code> 或 <code>1</code> 。</li>
</ul>
<p><strong>解法一</strong></p>
<p>和上面差不多，感觉应该是是easy。。。</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * type TreeNode struct &#123;</span></span><br><span class="line"><span class="comment"> *     Val int</span></span><br><span class="line"><span class="comment"> *     Left *TreeNode</span></span><br><span class="line"><span class="comment"> *     Right *TreeNode</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">pruneTree</span><span class="params">(root *TreeNode)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root == <span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    root.Left = pruneTree(root.Left)</span><br><span class="line">    root.Right = pruneTree(root.Right)</span><br><span class="line">    <span class="keyword">if</span> root.Left == <span class="literal">nil</span> &amp;&amp; root.Right==<span class="literal">nil</span> &amp;&amp; root.Val == <span class="number">0</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> root</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="965-单值二叉树"><a href="#965-单值二叉树" class="headerlink" title="965. 单值二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/univalued-binary-tree/" >965. 单值二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>题目就不copy了，二叉树只有一个值，水题</p>
<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isUnivalTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> dfs(root,root.val);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dfs</span><span class="params">(TreeNode root,<span class="keyword">int</span> val)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">return</span> root.val==val &amp;&amp; dfs(root.left,val) &amp;&amp; dfs(root.right,val);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1145-二叉树着色游戏"><a href="#1145-二叉树着色游戏" class="headerlink" title="1145. 二叉树着色游戏"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-coloring-game/" >1145. 二叉树着色游戏<i class="fas fa-external-link-alt"></i></a></h2><p>有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中，给出二叉树的根节点 <code>root</code>，树上总共有 <code>n</code> 个节点，且 <code>n</code> 为奇数，其中每个节点上的值从 <code>1</code> 到 <code>n</code> 各不相同。</p>
<p>游戏从「一号」玩家开始（「一号」玩家为红色，「二号」玩家为蓝色），最开始时，</p>
<p>「一号」玩家从 <code>[1, n]</code> 中取一个值 <code>x</code>（<code>1 &lt;= x &lt;= n</code>）；</p>
<p>「二号」玩家也从 <code>[1, n]</code> 中取一个值 <code>y</code>（<code>1 &lt;= y &lt;= n</code>）且 <code>y != x</code>。</p>
<p>「一号」玩家给值为 <code>x</code> 的节点染上红色，而「二号」玩家给值为 <code>y</code> 的节点染上蓝色。</p>
<p>之后两位玩家轮流进行操作，每一回合，玩家选择一个他之前涂好颜色的节点，将所选节点一个 <strong>未着色</strong> 的邻节点（即左右子节点、或父节点）进行染色。</p>
<p>如果当前玩家无法找到这样的节点来染色时，他的回合就会被跳过。</p>
<p>若两个玩家都没有可以染色的节点时，游戏结束。着色节点最多的那位玩家获得胜利 ✌️。</p>
<p>现在，假设你是「二号」玩家，根据所给出的输入，假如存在一个 <code>y</code> 值可以确保你赢得这场游戏，则返回 <code>true</code>；若无法获胜，就请返回 <code>false</code>。</p>
<p><strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/25/tpXUW6.png"
                      alt="tpXUW6.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>,<span class="number">11</span>], n = <span class="number">11</span>, x = <span class="number">3</span></span><br><span class="line">输出：True</span><br><span class="line">解释：第二个玩家可以选择值为 <span class="number">2</span> 的节点。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>二叉树的根节点为 <code>root</code>，树上由 <code>n</code> 个节点，节点上的值从 <code>1</code> 到 <code>n</code> 各不相同。</li>
<li><code>n</code> 为奇数。</li>
<li><code>1 &lt;= x &lt;= n &lt;= 100</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>第一个选手选择了一个节点之后，将二叉树实际上划分为了3个区域，左孩子区域，右孩子区域，还有父节点所在区域，三个区域以x为界限，没有交集，第二个选手需要在三个区域中选取一个区域，使自己能赢，很明显我们肯定要选最大的那个区域，所以我们只需要判断最大的区域是否比剩下其他部分和都要大就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">btreeGameWinningMove</span><span class="params">(TreeNode root, <span class="keyword">int</span> n, <span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">    dfs(root,x,n);</span><br><span class="line">    <span class="keyword">return</span> max&gt;n-max;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root,<span class="keyword">int</span> x,<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left=dfs(root.left,x,n);</span><br><span class="line">    <span class="keyword">int</span> right=dfs(root.right,x,n);</span><br><span class="line">    <span class="keyword">if</span>(root.val==x)&#123;</span><br><span class="line">        max=Math.max(left,max);</span><br><span class="line">        max=Math.max(right,max);</span><br><span class="line">        max=Math.max(n-left-right-<span class="number">1</span>,max);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left+right+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="993-二叉树的堂兄弟节点"><a href="#993-二叉树的堂兄弟节点" class="headerlink" title="993. 二叉树的堂兄弟节点"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/cousins-in-binary-tree/" >993. 二叉树的堂兄弟节点<i class="fas fa-external-link-alt"></i></a></h2><p>在二叉树中，根节点位于深度 <code>0</code> 处，每个深度为 <code>k</code> 的节点的子节点位于深度 <code>k+1</code> 处。</p>
<p>如果二叉树的两个节点深度相同，但<strong>父节点不同</strong>，则它们是一对<em>堂兄弟节点</em>。</p>
<p>我们给出了具有唯一值的二叉树的根节点 <code>root</code>，以及树中两个不同节点的值 <code>x</code> 和 <code>y</code>。</p>
<p>只有与值 <code>x</code> 和 <code>y</code> 对应的节点是堂兄弟节点时，才返回 <code>true</code>。否则，返回 <code>false</code>。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/06/05/tsO8yR.png"
                      alt="tsO8yR.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>], x = <span class="number">4</span>, y = <span class="number">3</span></span><br><span class="line">输出：<span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/06/05/tsOYex.png"
                      alt="tsOYex.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">5</span>], x = <span class="number">5</span>, y = <span class="number">4</span></span><br><span class="line">输出：<span class="keyword">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/06/05/tsOaFO.png"
                      alt="tsOaFO.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">4</span>], x = <span class="number">2</span>, y = <span class="number">3</span></span><br><span class="line">输出：<span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li>二叉树的节点数介于 <code>2</code> 到 <code>100</code> 之间。</li>
<li>每个节点的值都是唯一的、范围为 <code>1</code> 到 <code>100</code> 的整数。</li>
</ol>
<p><strong>解法一</strong></p>
<p>二叉树水题（3天没刷新题了，再不刷几道实在是说不过其了，刷题还是要保持手感啊）</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">isCousins</span><span class="params">(root *TreeNode, x <span class="keyword">int</span>, y <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> depX = <span class="number">-1</span></span><br><span class="line">    <span class="keyword">var</span> pX *TreeNode</span><br><span class="line">    <span class="keyword">var</span> depY = <span class="number">-1</span></span><br><span class="line">    <span class="keyword">var</span> pY *TreeNode</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root, parent *TreeNode, x, y <span class="keyword">int</span>, depth <span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root, parent *TreeNode, x, y <span class="keyword">int</span>, depth <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123; <span class="comment">//按题目说的这里其实不需要</span></span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> root.Val == x &#123;</span><br><span class="line">            depX = depth</span><br><span class="line">            pX = parent</span><br><span class="line">            <span class="comment">//结束该子树的搜索，加快速度，下面即使有Y也肯定不是X的堂兄弟</span></span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> root.Val == y &#123;</span><br><span class="line">            depY = depth</span><br><span class="line">            pY = parent</span><br><span class="line">            <span class="comment">//同上</span></span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Left, root, x, y, depth+<span class="number">1</span>)</span><br><span class="line">        dfs(root.Right, root, x, y, depth+<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root, <span class="literal">nil</span>, x, y, <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">return</span> pX != pY &amp;&amp; depX == depY</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>有一个小的优化点还是挺有意思的，就是return的地方，一开始没考虑这么多，AC了之后感觉不对，是不是LC又少CASE了，结果仔细一想发现这里是个优化点😁</p>
<h2 id="440-字典序的第K小数字"><a href="#440-字典序的第K小数字" class="headerlink" title="440. 字典序的第K小数字"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/k-th-smallest-in-lexicographical-order/" >440. 字典序的第K小数字<i class="fas fa-external-link-alt"></i></a></h2><p>给定整数 <code>n</code> 和 <code>k</code>，找到 <code>1</code> 到 <code>n</code> 中字典序第 <code>k</code> 小的数字。</p>
<p>注意：1 ≤ k ≤ n ≤ 1e9。</p>
<p><strong>示例 :</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">n: <span class="number">13</span>   k: <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出:</span><br><span class="line"><span class="number">10</span></span><br><span class="line"></span><br><span class="line">解释:</span><br><span class="line">字典序的排列是 [<span class="number">1</span>, <span class="number">10</span>, <span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]，所以第二小的数字是 <span class="number">10</span>。</span><br></pre></td></tr></table></figure>
<p><strong>解法一</strong></p>
<p>一开始看了评论区说了10叉树,然后我就顺着这个思路去想了,然后就直接去前序遍历了,然后就T了,这里看下数据范围就知道肯定是过不了的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//TLE</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findKthNumber</span><span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=<span class="number">9</span>;i++) &#123;</span><br><span class="line">        dfs(i,n,k);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> idx=<span class="number">0</span>,res=-<span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> cur,<span class="keyword">int</span> n,<span class="keyword">int</span> k)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(res!=-<span class="number">1</span>) <span class="keyword">return</span>;</span><br><span class="line">    <span class="keyword">if</span>(cur&gt;n) <span class="keyword">return</span>;</span><br><span class="line">    idx++;</span><br><span class="line">    <span class="keyword">if</span>(k==idx)&#123;</span><br><span class="line">        res=cur;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;=<span class="number">9</span>;i++) &#123;</span><br><span class="line">        dfs(cur*<span class="number">10</span>+i,n,k);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>直接遍历肯定是行不通,那么就只能想办法跳过一些节点,这里我们就可以通过计算每个节点的子节点的个数来判断第k个是不是在该节点下,而子节点的个数就可以用<code>Min(n+1,next*10)-cur</code>计算得到,<code>next</code>是和cur相邻的节点,<code>n</code>是最大值,画个图就懂了<br><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20200614/3WPecCGnzxQl.png?imageslim"
                      alt="mark"
                ></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//UPDATE: 2020.7.29 之前的代码细节有的不好理解，重写了一版</span></span><br><span class="line"><span class="comment">//正解</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findKthNumber</span><span class="params">(n <span class="keyword">int</span>, k <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="comment">//k和count都是从1开始</span></span><br><span class="line">    <span class="keyword">var</span> cur = <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> k &gt; <span class="number">1</span> &#123;</span><br><span class="line">        count := getChild(cur, n)</span><br><span class="line">        <span class="keyword">if</span> count &lt; k &#123; <span class="comment">//不在该节点下，切换成兄弟节点</span></span><br><span class="line">            cur++ </span><br><span class="line">            k-=count</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123; <span class="comment">//在该节点下，切换成子节点</span></span><br><span class="line">            cur *= <span class="number">10</span></span><br><span class="line">            k--</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> cur</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//当前节点下有多少个子节点，也就是以cur开头的有多少个（包括cur）</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">getChild</span><span class="params">(cur <span class="keyword">int</span>, n <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> next = cur+<span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> cur &lt;= n &#123;</span><br><span class="line">        count += Min(n+<span class="number">1</span>, next) - cur</span><br><span class="line">        cur *= <span class="number">10</span></span><br><span class="line">        next *= <span class="number">10</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Min</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> a &lt; b &#123;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> b</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<h2 id="386-字典序排数"><a href="#386-字典序排数" class="headerlink" title="386. 字典序排数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/lexicographical-numbers/" >386. 字典序排数<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个整数 n, 返回从 1 到 n 的字典顺序。</p>
<p>例如，</p>
<p>给定 n =1 3，返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。</p>
<p>请尽可能的优化算法的时间复杂度和空间复杂度。 输入的数据 n 小于等于 5,000,000。</p>
<p><strong>解法一</strong></p>
<p>先做的上面那一题,再做这一题就简单多了,前面tle的方法就是这里的正解,十叉树的前序遍历</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">lexicalOrder</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=<span class="number">9</span>;i++)&#123;</span><br><span class="line">        dfs(i,n);   </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> cur,<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(cur&gt;n) <span class="keyword">return</span>;</span><br><span class="line">    res.add(cur);</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;=<span class="number">9</span>;i++)&#123;</span><br><span class="line">        dfs(cur*<span class="number">10</span>+i,n);   </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="1028-从先序遍历还原二叉树"><a href="#1028-从先序遍历还原二叉树" class="headerlink" title="1028. 从先序遍历还原二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/recover-a-tree-from-preorder-traversal/" >1028. 从先序遍历还原二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>我们从二叉树的根节点 root 开始进行深度优先搜索。</p>
<p>在遍历中的每个节点处，我们输出 D 条短划线（其中 D 是该节点的深度），然后输出该节点的值。（如果节点的深度为 D，则其直接子节点的深度为 D + 1。根节点的深度为 0）。</p>
<p>如果节点只有一个子节点，那么保证该子节点为左子节点。</p>
<p>给出遍历输出 S，还原树并返回其根节点 root。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;1-2--3--4-5--6--7&quot;</span></span><br><span class="line">输出：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">7</span>]</span><br></pre></td></tr></table></figure>
<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;1-2--3---4-5--6---7&quot;</span></span><br><span class="line">输出：[<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">6</span>,<span class="keyword">null</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">7</span>]</span><br></pre></td></tr></table></figure>
<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：<span class="string">&quot;1-401--349---90--88&quot;</span></span><br><span class="line">输出：[<span class="number">1</span>,<span class="number">401</span>,<span class="keyword">null</span>,<span class="number">349</span>,<span class="number">88</span>,<span class="number">90</span>]</span><br></pre></td></tr></table></figure>
<p><strong>提示：</strong><br>原始树中的节点数介于 1 和 1000 之间。<br>每个节点的值介于 1 和 10 ^ 9 之间。</p>
<p><strong>解法一</strong></p>
<p>抄答案，第一天看了几分钟，一开始想写递归，直接看了答案，第二天还是没有完整的写出来，其实这题迭代会好理解很多，递归的看了下，有点不好理解，很trick</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> TreeNode <span class="title">recoverFromPreorder</span><span class="params">(String S)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//栈中存的是深度严格单调递增（步伐为1）的节点 0 1 2 3 4....</span></span><br><span class="line">    Deque&lt;TreeNode&gt; stack=<span class="keyword">new</span> ArrayDeque(); </span><br><span class="line">    <span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(i&lt;S.length())&#123;</span><br><span class="line">        <span class="keyword">int</span> depth=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;S.length() &amp;&amp; S.charAt(i)==<span class="string">&#x27;-&#x27;</span>) &#123;</span><br><span class="line">            depth++;</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">int</span> val=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;S.length() &amp;&amp; S.charAt(i)&gt;=<span class="string">&#x27;0&#x27;</span> &amp;&amp; S.charAt(i)&lt;=<span class="string">&#x27;9&#x27;</span>)&#123;</span><br><span class="line">            val=val*<span class="number">10</span>+S.charAt(i)-<span class="number">48</span>;</span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">        TreeNode node=<span class="keyword">new</span> TreeNode(val);</span><br><span class="line">        <span class="keyword">if</span>(depth==stack.size())&#123; <span class="comment">//栈的节点数量就是当前的深度</span></span><br><span class="line">            <span class="keyword">if</span>(!stack.isEmpty()) stack.peek().left=node;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">while</span>(depth!=stack.size())&#123;</span><br><span class="line">                stack.pop();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//depth==0的只有一个根节点，是不会走这个分支的，所以这里肯定不为空</span></span><br><span class="line">            stack.peek().right=node;</span><br><span class="line">        &#125;</span><br><span class="line">        stack.push(node);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(stack.size()!=<span class="number">1</span>) stack.pop();</span><br><span class="line">    <span class="keyword">return</span> stack.pop();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="897-递增顺序查找树"><a href="#897-递增顺序查找树" class="headerlink" title="897. 递增顺序查找树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/increasing-order-search-tree/" >897. 递增顺序查找树<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个树，请你 按中序遍历 重新排列树，使树中最左边的结点现在是树的根，并且每个结点没有左子结点，只有一个右子结点。</p>
<p><strong>示例 ：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">5</span>,<span class="number">3</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">8</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">7</span>,<span class="number">9</span>]</span><br><span class="line"></span><br><span class="line">       <span class="number">5</span></span><br><span class="line">      / \</span><br><span class="line">    <span class="number">3</span>    <span class="number">6</span></span><br><span class="line">   / \    \</span><br><span class="line">  <span class="number">2</span>   <span class="number">4</span>    <span class="number">8</span></span><br><span class="line"> /        / \ </span><br><span class="line"><span class="number">1</span>        <span class="number">7</span>   <span class="number">9</span></span><br><span class="line"></span><br><span class="line">输出：[<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">2</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">4</span>,<span class="keyword">null</span>,<span class="number">5</span>,<span class="keyword">null</span>,<span class="number">6</span>,<span class="keyword">null</span>,<span class="number">7</span>,<span class="keyword">null</span>,<span class="number">8</span>,<span class="keyword">null</span>,<span class="number">9</span>]</span><br><span class="line"></span><br><span class="line"> <span class="number">1</span></span><br><span class="line">  \</span><br><span class="line">   <span class="number">2</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">3</span></span><br><span class="line">      \</span><br><span class="line">       <span class="number">4</span></span><br><span class="line">        \</span><br><span class="line">         <span class="number">5</span></span><br><span class="line">          \</span><br><span class="line">           <span class="number">6</span></span><br><span class="line">            \</span><br><span class="line">             <span class="number">7</span></span><br><span class="line">              \</span><br><span class="line">               <span class="number">8</span></span><br><span class="line">                \</span><br><span class="line">                 <span class="number">9</span>  </span><br></pre></td></tr></table></figure>
<p> <br><strong>提示：</strong></p>
<p>给定树中的结点数介于 1 和 100 之间。每个结点都有一个从 0 到 1000 范围内的唯一整数值。</p>
<p><strong>解法一</strong></p>
<p>go中序遍历配合全局变量，没啥好说的（看评论区很多人直接new TreeNode感觉不太好吧，题目的意思不是在原树上改么？）</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">increasingBST</span><span class="params">(root *TreeNode)</span> *<span class="title">TreeNode</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span></span><br><span class="line">    dummyNode:=&amp;TreeNode&#123;&#125;</span><br><span class="line">    last:=dummyNode</span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> root==<span class="literal">nil</span>&#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Left)</span><br><span class="line">        root.Left=<span class="literal">nil</span></span><br><span class="line">        last.Right=root</span><br><span class="line">        last = root</span><br><span class="line">        dfs(root.Right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> dummyNode.Right</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>这题和<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binode-lcci/" >面试题 17.12. BiNode<i class="fas fa-external-link-alt"></i></a>解法是一摸一样的，但是这个sb题的描述我是真没看懂，结合评论区和case才知道到底要干啥，看评论区好像都整的挺明白的，一度以为我理解能力出了问题</p>
</blockquote>
<h2 id="979-在二叉树中分配硬币"><a href="#979-在二叉树中分配硬币" class="headerlink" title="979. 在二叉树中分配硬币"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/distribute-coins-in-binary-tree/" >979. 在二叉树中分配硬币<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给定一个有 <code>N</code> 个结点的二叉树的根结点 <code>root</code>，树中的每个结点上都对应有 <code>node.val</code> 枚硬币，并且总共有 <code>N</code> 枚硬币。</p>
<p>在一次移动中，我们可以选择两个相邻的结点，然后将一枚硬币从其中一个结点移动到另一个结点。(移动可以是从父结点到子结点，或者从子结点移动到父结点。)。</p>
<p>返回使每个结点上只有一枚硬币所需的移动次数。</p>
<p><strong>示例 1：</strong><br><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://upload.cc/i1/2020/07/07/w2G7JY.png"
                      alt="UTOOLS1594052444483.png"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">3</span>,<span class="number">0</span>,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：从树的根结点开始，我们将一枚硬币移到它的左子结点上，一枚硬币移到它的右子结点上。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://upload.cc/i1/2020/07/07/kPOvxa.png"
                      alt="UTOOLS1594052495418.png"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">0</span>,<span class="number">3</span>,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：从根结点的左子结点开始，我们将两枚硬币移到根结点上 [移动两次]。然后，我们把一枚硬币从根结点移到右子结点上。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://upload.cc/i1/2020/07/07/j4YpZS.png"
                      alt="UTOOLS1594052508155.png"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">0</span>,<span class="number">2</span>]</span><br><span class="line">输出：<span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://upload.cc/i1/2020/07/07/DYZ6cE.png"
                      alt="UTOOLS1594052519453.png"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,null,<span class="number">3</span>]</span><br><span class="line">输出：<span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li> <code>1&lt;= N &lt;= 100</code></li>
<li> <code>0 &lt;= node.val &lt;= N</code></li>
</ol>
<p><strong>解法一</strong></p>
<p>一开始直接想出来的做法，后面看了其他人的解法发现还不太一样😂，不过我还是感觉我的方法更好理解</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//闭包的写法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">distributeCoins</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> Abs = <span class="function"><span class="keyword">func</span><span class="params">(a <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; <span class="number">0</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> -a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//dfs返回树的节点数量 和 金币数量</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode)</span> <span class="params">(<span class="keyword">int</span>, <span class="keyword">int</span>)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span> <span class="params">(<span class="keyword">int</span>, <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>, <span class="number">0</span></span><br><span class="line">        &#125;</span><br><span class="line">        lCount, lCoins := dfs(root.Left)</span><br><span class="line">        <span class="comment">//其实两者的差值就是需要经过该节点中转的次数</span></span><br><span class="line">        <span class="comment">//统计出所有节点的中转次数就是整体的转移次数</span></span><br><span class="line">        res += Abs(lCount - lCoins)</span><br><span class="line">        rCount, rCoins := dfs(root.Right)</span><br><span class="line">        res += Abs(rCount - rCoins)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span> + lCount + rCount, root.Val + lCoins + rCoins</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>其他人的做法，dfs返回节点的盈亏值（节点数和金币数的差值），盈亏值绝对值之和就是总体的转移次数（所以两种解法其实是一样的，只是计算的时间不一样，我的是函数返回后计算盈亏，而下面的解法是返回前计算盈亏，感觉我的更好理解😂）</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//另一种做法</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">distributeCoins</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> Abs = <span class="function"><span class="keyword">func</span><span class="params">(a <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a &lt; <span class="number">0</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> -a</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> a</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode)</span> <span class="title">int</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">        &#125;</span><br><span class="line">        left := dfs(root.Left)</span><br><span class="line">        right := dfs(root.Right)</span><br><span class="line">        res += Abs(left) + Abs(right)</span><br><span class="line">        <span class="keyword">return</span> root.Val + left + right - <span class="number">1</span></span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="99-恢复二叉搜索树"><a href="#99-恢复二叉搜索树" class="headerlink" title="99. 恢复二叉搜索树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/recover-binary-search-tree/" >99. 恢复二叉搜索树<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>二叉搜索树中的两个节点被错误地交换。</p>
<p>请在不改变其结构的情况下，恢复这棵树。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,null,null,<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">   <span class="number">1</span></span><br><span class="line">  /</span><br><span class="line"> <span class="number">3</span></span><br><span class="line">  \</span><br><span class="line">   <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出: [<span class="number">3</span>,<span class="number">1</span>,null,null,<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">   <span class="number">3</span></span><br><span class="line">  /</span><br><span class="line"> <span class="number">1</span></span><br><span class="line">  \</span><br><span class="line">   <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">3</span>,<span class="number">1</span>,<span class="number">4</span>,null,null,<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">4</span></span><br><span class="line">   /</span><br><span class="line">  <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出: [<span class="number">2</span>,<span class="number">1</span>,<span class="number">4</span>,null,null,<span class="number">3</span>]</span><br><span class="line"></span><br><span class="line">  <span class="number">2</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">1</span>   <span class="number">4</span></span><br><span class="line">   /</span><br><span class="line">  <span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>进阶:</strong></p>
<ul>
<li>  使用 O(<em>n</em>) 空间复杂度的解法很容易实现。</li>
<li>  你能想出一个只使用常数空间的解决方案吗？</li>
</ul>
<p><strong>解法一</strong></p>
<p>中序遍历，记录下位置不对的节点，最后交换他们的值就行了</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">recoverTree</span><span class="params">(root *TreeNode)</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> node1 *TreeNode</span><br><span class="line">    <span class="keyword">var</span> node2 *TreeNode</span><br><span class="line">    <span class="comment">//这里犯了一个错误，一开始给pre赋值了一个root,导致节点记录错了</span></span><br><span class="line">    <span class="keyword">var</span> pre *TreeNode</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode)</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Left)</span><br><span class="line">        <span class="keyword">if</span> pre != <span class="literal">nil</span> &amp;&amp; root.Val &lt; pre.Val &#123;</span><br><span class="line">            <span class="keyword">if</span> node1 == <span class="literal">nil</span> &#123;</span><br><span class="line">                node1 = pre</span><br><span class="line">            &#125;</span><br><span class="line">            node2 = root</span><br><span class="line">        &#125;</span><br><span class="line">        pre = root</span><br><span class="line">        dfs(root.Right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    node1.Val, node2.Val = node2.Val, node1.Val</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这种解法严格来说空间复杂度并不是O(1)，递归会有系统栈的开销，空间复杂度应该是O(h)，h是树的高度，真正的O(1)的做法应该是Morris遍历，这种解法就称得上hard了</p>
<h2 id="1302-层数最深叶子节点的和"><a href="#1302-层数最深叶子节点的和" class="headerlink" title="1302. 层数最深叶子节点的和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/deepest-leaves-sum/" >1302. 层数最深叶子节点的和<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给你一棵二叉树，请你返回层数最深的叶子节点的和。</p>
<p><strong>示例：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/09/06/wmC0aT.png"
                      alt="wmC0aT.png"
                ></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入：root = [1,2,3,4,5,null,6,7,null,null,null,null,8]</span><br><span class="line">输出：15</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  树中节点数目在 <code>1</code> 到 <code>10^4</code> 之间。</li>
<li>  每个节点的值在 <code>1</code> 到 <code>100</code> 之间。</li>
</ul>
<p><strong>解法一</strong></p>
<p>BFS没啥好说的，DFS的挺有意思</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">deepestLeavesSum</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(*TreeNode, <span class="keyword">int</span>)</span></span></span><br><span class="line">    <span class="keyword">var</span> maxDep = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> sum = <span class="number">0</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode, dep <span class="keyword">int</span>)</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> maxDep == dep &#123;</span><br><span class="line">            sum += root.Val</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> dep &gt; maxDep &#123;</span><br><span class="line">            sum = root.Val</span><br><span class="line">            maxDep = dep</span><br><span class="line">        &#125;</span><br><span class="line">        dfs(root.Left, dep+<span class="number">1</span>)</span><br><span class="line">        dfs(root.Right, dep+<span class="number">1</span>)</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root, <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">return</span> sum</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="树形DP-大概"><a href="#树形DP-大概" class="headerlink" title="树形DP(大概)"></a><em>树形DP(大概)</em></h2><blockquote>
<p>2020.5.10更新，在看了左神的书后，大概了解了树形DP，所谓的树形DP实际上就是把递推方程搬到了树结构上，按我的理解树形DP很大的特点就是最终的解可能存在于树上每个节点，像我下面的题有的暴力解用的就是双重递归，就是dfs遍历没个节点，然后再对每个节点递归求解，但是对根节点求解的时候，实际上其他的子节点都成了子问题，所以后面再对子节点求解的时候问题就重复了，所以就可以采用后序遍历，自底向上，先求左右节点的值再更新根节点，<strong>下面的题其实我不知道到底是不是属于树形DP，可能太简单了，但是再我看来解法比较统一，很有套路所以整理到一起</strong>，我查了下网上介绍的树形DP还是挺难的，后面有时间了解后再来记录</p>
</blockquote>
<h2 id="110-平衡二叉树"><a href="#110-平衡二叉树" class="headerlink" title="110. 平衡二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/balanced-binary-tree/" >110. 平衡二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，判断它是否是高度平衡的二叉树。</p>
<p>本题中，一棵高度平衡二叉树定义为：</p>
<blockquote>
<p> 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1</p>
</blockquote>
<p><strong>示例 1:</strong></p>
<p>给定二叉树 [3,9,20,null,null,15,7]</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">  <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">9</span>  <span class="number">20</span></span><br><span class="line">  /  \</span><br><span class="line"> <span class="number">15</span>   <span class="number">7</span></span><br></pre></td></tr></table></figure>

<p>返回 true 。</p>
<p><strong>示例 2:</strong></p>
<p>给定二叉树 [1,2,2,3,3,null,null,4,4]</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">      <span class="number">1</span></span><br><span class="line">     / \</span><br><span class="line">    <span class="number">2</span>   <span class="number">2</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">3</span>   <span class="number">3</span></span><br><span class="line"> / \</span><br><span class="line"><span class="number">4</span>   <span class="number">4</span></span><br></pre></td></tr></table></figure>


<p>返回 false 。</p>
<p><strong>解法一</strong></p>
<p>暴力法，结合上面的[二叉树最大深度](#104. 二叉树的最大深度)，<strong>自顶向下</strong>，求左右子树的高度差</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//top 2 bottom</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isBalanced</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">if</span> (Math.abs(hight(root.left)-hight(root.right))&gt;<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> isBalanced(root.left) &amp;&amp; isBalanced(root.right);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hight</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Math.max(hight(root.right),hight(root.left))+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>自顶向下，先判断根节点，然后判断左右子树，很明显。在判断左右子树的时候，会重复的遍历判断根节点的时候已经遍历过的节点，时间复杂度应该是<code>O(N^2)</code></p>
<p><strong>解法二</strong></p>
<p>自底向上，利用一个实例变量保存结果，其实就是在上面的求heigh过程中将左右子树的高度先取出来直接比较，如果差距大于1就直接记录下结果false，但是其实这里还是可以优化下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> ans=<span class="keyword">true</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//buttom 2 top</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isBalanced</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    hight(root);</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hight</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//递归分治，自底向上，在求高度的过程中计算左右高度差</span></span><br><span class="line">    <span class="keyword">int</span> left=hight(root.left);</span><br><span class="line">    <span class="keyword">int</span> right=hight(root.right);</span><br><span class="line">    <span class="keyword">if</span> (Math.abs(left-right)&gt;<span class="number">1</span>) &#123;</span><br><span class="line">        ans=<span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Math.max(left,right)+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>自底向上，只需要遍历一遍二叉树就可以得到结果，时间复杂度<code>O(N)</code> </p>
<p><strong>解法三</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isBalanced</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    <span class="keyword">return</span> hight(root)!=-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hight</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=hight(root.left);</span><br><span class="line">    <span class="keyword">if</span> (left==-<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> right=hight(root.right);</span><br><span class="line">    <span class="keyword">if</span> (right==-<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> Math.abs(left-right)&gt;<span class="number">1</span>?-<span class="number">1</span>:Math.max(left,right)+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在不符合的时候一路<code>return -1</code> 节省后面的计算</p>
<h2 id="563-二叉树的坡度"><a href="#563-二叉树的坡度" class="headerlink" title="563. 二叉树的坡度"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-tilt/" >563. 二叉树的坡度<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，计算整个树的坡度。</p>
<p>一个树的节点的坡度定义即为，该节点左子树的结点之和和右子树结点之和的差的绝对值。空结点的的坡度是0。</p>
<p>整个树的坡度就是其所有节点的坡度之和。</p>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: </span><br><span class="line">         <span class="number">1</span></span><br><span class="line">       /   \</span><br><span class="line">      <span class="number">2</span>     <span class="number">3</span></span><br><span class="line">输出: <span class="number">1</span></span><br><span class="line">解释: </span><br><span class="line">结点的坡度 <span class="number">2</span> : <span class="number">0</span></span><br><span class="line">结点的坡度 <span class="number">3</span> : <span class="number">0</span></span><br><span class="line">结点的坡度 <span class="number">1</span> : |<span class="number">2</span>-<span class="number">3</span>| = <span class="number">1</span></span><br><span class="line">树的坡度 : <span class="number">0</span> + <span class="number">0</span> + <span class="number">1</span> = <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong></p>
<ol>
<li>任何子树的结点的和不会超过32位整数的范围。</li>
<li>坡度的值不会超过32位整数的范围。. </li>
</ol>
<p><strong>解法一</strong></p>
<p>很快写出来的解法，发现这题和上面的 <strong>平衡二叉树</strong> 有异曲同工之妙！</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//首先想到的解法</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findTilt</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> findTilt(root.left)+findTilt(root.right)+Math.abs(childSum(root.left)-childSum(root.right));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">childSum</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> childSum(root.left)+childSum(root.right)+root.val;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>嵌套递归，相当暴力</p>
<p><strong>解法二</strong></p>
<p>上面的做法确实有点可惜，其实在计算childSum的时候就可以字节把坡度算出来然后累加就是整体的坡度</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span> tilt=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//结果发现上面的做法傻逼了。。。其实我知道是不对的,但是不知道咋改,不过写了个嵌套递归也还行hahaha</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findTilt</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    childSum(root);</span><br><span class="line">    <span class="keyword">return</span> tilt;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">childSum</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=childSum(root.left);</span><br><span class="line">    <span class="keyword">int</span> right=childSum(root.right);</span><br><span class="line">    tilt+=Math.abs(left-right);</span><br><span class="line">    <span class="keyword">return</span> left+right+root.val;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="543-二叉树的直径"><a href="#543-二叉树的直径" class="headerlink" title="543. 二叉树的直径"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/diameter-of-binary-tree/" >543. 二叉树的直径<i class="fas fa-external-link-alt"></i></a></h2><p>给定一棵二叉树，你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。</p>
<p><strong>示例 :</strong><br>给定二叉树</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">2</span>   <span class="number">3</span></span><br><span class="line"> / \     </span><br><span class="line"><span class="number">4</span>   <span class="number">5</span>    </span><br></pre></td></tr></table></figure>
<p>返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。</p>
<p><strong>注意：</strong>两结点之间的路径长度是以它们之间边的数目表示</p>
<p><strong>解法一</strong></p>
<p>树的题目做多了，发现其实也就几种题型，都很熟悉，这题就和上面的 <a href="">二叉树的坡度</a> ，<a href="">平衡二叉树</a> 很类似，这题需要注意<strong>直径不一定过根节点</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span> max=Integer.MIN_VALUE;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">diameterOfBinaryTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    hight(root);</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hight</span><span class="params">(TreeNode node)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (node==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=hight(node.left);</span><br><span class="line">    <span class="keyword">int</span> right=hight(node.right);</span><br><span class="line">    max=Math.max(left+right,max);</span><br><span class="line">    <span class="keyword">return</span> Math.max(left,right)+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>和之前一样，先写了个暴力的嵌套递归😂，代码确实简介，难道这就是暴力美学么，i了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">diameterOfBinaryTree</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> root==<span class="keyword">null</span>?<span class="number">0</span>:Math.max(hight(root.left)+hight(root.right),Math.max(diameterOfBinaryTree(root.right),diameterOfBinaryTree(root.left)));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hight</span><span class="params">(TreeNode node)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> node==<span class="keyword">null</span>?<span class="number">0</span>:Math.max(hight(node.left),hight(node.right))+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="124-二叉树中的最大路径和"><a href="#124-二叉树中的最大路径和" class="headerlink" title="124. 二叉树中的最大路径和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/" >124. 二叉树中的最大路径和<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个<strong>非空</strong>二叉树，返回其最大路径和。</p>
<p>本题中，路径被定义为一条从树中任意节点出发，达到任意节点的序列。该路径至少包含一个节点，且不一定经过根节点。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br><span class="line">   <span class="number">1</span></span><br><span class="line">  / \</span><br><span class="line"> <span class="number">2</span>   <span class="number">3</span></span><br><span class="line">输出: <span class="number">6</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [-<span class="number">10</span>,<span class="number">9</span>,<span class="number">20</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">15</span>,<span class="number">7</span>]</span><br><span class="line">   -<span class="number">10</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">9</span>  <span class="number">20</span></span><br><span class="line">    /  \</span><br><span class="line">   <span class="number">15</span>   <span class="number">7</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">42</span></span><br></pre></td></tr></table></figure>

<p><strong>错误解法</strong></p>
<p>先上一个错误答案，过了 <code>71/93</code> 个case（lc的case好少）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxPathSum</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> Integer.MIN_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=helper(root);</span><br><span class="line">    <span class="keyword">return</span> Math.max(res,Math.max(maxPathSum(root.left),maxPathSum(root.right)));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//以当前节点为根的最大路径和</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">helper</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> Integer.MIN_VALUE;;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=helper(root.left);</span><br><span class="line">    <span class="keyword">int</span> right=helper(root.right);</span><br><span class="line">    <span class="keyword">return</span> root.val+(left&gt;<span class="number">0</span>?left:<span class="number">0</span>)+(right&gt;<span class="number">0</span>?right:<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我一开始的想法是按照根节点来讨论的，每个节点的最大值就是 左右子树的最大路径和（大于0）加上当前节点的值，改了半天WA了几发后发现是有问题的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">     <span class="number">1</span> </span><br><span class="line">   /   \</span><br><span class="line">  <span class="number">2</span>     <span class="number">3</span></span><br><span class="line"> / \   / \</span><br><span class="line"><span class="number">7</span>   <span class="number">9</span>  <span class="number">5</span>  <span class="number">6</span></span><br></pre></td></tr></table></figure>

<p>比如这样的，2为根的最长路径是1，2，9但是这个在1为根的节点中是不合法的，所以我们需要的只有单边的路径和，如上图的树，我们需要的就是 <code>2-&gt;9</code> 这条路径，所以我们需要再添加一个求最长路径的函数</p>
<p><strong>解法二</strong></p>
<p>可AC，但是效率较低</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxPathSum</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> Integer.MIN_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=helper(root);</span><br><span class="line">    <span class="keyword">return</span> Math.max(res,Math.max(maxPathSum(root.left),maxPathSum(root.right)));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//以当前节点为根的最大路径和(双边)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">helper</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> Integer.MIN_VALUE;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=dfs(root.left);</span><br><span class="line">    <span class="keyword">int</span> right=dfs(root.right);</span><br><span class="line">    <span class="keyword">return</span> root.val+(left&gt;<span class="number">0</span>?left:<span class="number">0</span>)+(right&gt;<span class="number">0</span>?right:<span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//root为起始节点的最大路径和(单边)</span></span><br><span class="line"><span class="comment">//这里可以cache一下</span></span><br><span class="line"><span class="comment">//cache 前 219ms</span></span><br><span class="line"><span class="comment">//cache 后 30ms</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>  HashMap&lt;String,Integer&gt; cache=<span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> Integer.MIN_VALUE;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (cache.containsKey(root.toString())) &#123;</span><br><span class="line">        <span class="keyword">return</span> cache.get(root.toString());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=dfs(root.left);</span><br><span class="line">    <span class="keyword">int</span> right=dfs(root.right);</span><br><span class="line">    <span class="keyword">int</span> max=Math.max(left,right);</span><br><span class="line">    cache.put(root.toString(),root.val+(max&gt;<span class="number">0</span>?max:<span class="number">0</span>));</span><br><span class="line">    <span class="keyword">return</span> root.val+(max&gt;<span class="number">0</span>?max:<span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法三</strong></p>
<p>这个解法其实就是将我前面的代码逻辑简化了，核心的思路还是一样的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> res=Integer.MIN_VALUE;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxPathSum</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    helper(root);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//返回以当前节点为*起点*的最大路径和(单边,左右子树中选最大的一个)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">helper</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left=Math.max(helper(root.left),<span class="number">0</span>);</span><br><span class="line">    <span class="keyword">int</span> right=Math.max(helper(root.right),<span class="number">0</span>);</span><br><span class="line">    res=Math.max(res,root.val+left+right); <span class="comment">//在这里记录最大值</span></span><br><span class="line">    <span class="keyword">return</span> root.val+Math.max(left,right); <span class="comment">//返回的实际上是我上面dfs的结果</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在递归函数中用全局变量记录最大值，最后返回的却是<strong>单边</strong>的最大值，也就是我上面写的dfs函数返回的值，可以说是相当巧妙了，除此外对递归的出口也进行了简化</p>
<p><strong>Update: 2020.6.21</strong></p>
<p>用go重写一下，最近很喜欢写这种闭包的结构，感觉比较简洁</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">maxPathSum</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    res:=<span class="number">-1</span>&lt;&lt;<span class="number">31</span></span><br><span class="line">    <span class="keyword">var</span> Max =<span class="function"><span class="keyword">func</span><span class="params">(a,b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> a&gt;b&#123;</span><br><span class="line">            <span class="keyword">return</span> a   </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//以root开头最大单侧路径</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> root==<span class="literal">nil</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">-1</span>&lt;&lt;<span class="number">31</span> <span class="comment">//返回的小于0就行</span></span><br><span class="line">        &#125;</span><br><span class="line">        left:=Max(<span class="number">0</span>,dfs(root.Left))</span><br><span class="line">        right:=Max(<span class="number">0</span>,dfs(root.Right))</span><br><span class="line">        res=Max(res,left+right+root.Val)</span><br><span class="line">        <span class="keyword">return</span> root.Val+Max(left,right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="687-最长同值路径"><a href="#687-最长同值路径" class="headerlink" title="687. 最长同值路径"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-univalue-path/" >687. 最长同值路径<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个二叉树，找到最长的路径，这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。</p>
<p><strong>注意</strong>：两个节点之间的路径长度由它们之间的边数表示。</p>
<p><strong>示例 1:</strong></p>
<p>输入:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">5</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">4</span>   <span class="number">5</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">1</span>   <span class="number">1</span>   <span class="number">5</span></span><br></pre></td></tr></table></figure>

<p>输出:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<p>输入:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">    <span class="number">1</span></span><br><span class="line">   / \</span><br><span class="line">  <span class="number">4</span>   <span class="number">5</span></span><br><span class="line"> / \   \</span><br><span class="line"><span class="number">4</span>   <span class="number">4</span>   <span class="number">5</span></span><br></pre></td></tr></table></figure>

<p>输出:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>注意:</strong> 给定的二叉树不超过10000个结点。 树的高度不超过1000。</p>
<p><strong>错误解法</strong></p>
<p>其实写了一会儿就意识到和上面的<a href="#124-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E8%B7%AF%E5%BE%84%E5%92%8C">124.二叉树的最大路径和</a>，<a href="#543-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84">543.二叉树的直径</a>是一样的思路，但是自己还是没写好，递归函数的写着写着就写变了，脱离了最开始的定义</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//错误解法，其实整体思路是对的，但是细节没处理好</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestUnivaluePath</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> leftMax=dfs(root.left);</span><br><span class="line">    <span class="keyword">int</span> rightMax=dfs(root.right);</span><br><span class="line">    <span class="keyword">int</span> flag=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span>(root.left!=<span class="keyword">null</span> &amp;&amp; root.left.val==root.val)&#123;</span><br><span class="line">        flag++;</span><br><span class="line">        leftMax++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root.right!=<span class="keyword">null</span> &amp;&amp; root.right.val==root.val)&#123;</span><br><span class="line">        flag++;</span><br><span class="line">        rightMax++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(flag==<span class="number">2</span>)&#123;</span><br><span class="line">        res=Math.max(res,leftMax+rightMax);</span><br><span class="line">    &#125;</span><br><span class="line">    res=Math.max(res,Math.max(leftMax,rightMax));</span><br><span class="line">    <span class="keyword">return</span> flag==<span class="number">0</span>?<span class="number">0</span>:Math.max(leftMax,rightMax);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>在看了题解后对上面错误解法的纠正</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestUnivaluePath</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//以root开头的同值路径长度</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> leftMax=dfs(root.left);</span><br><span class="line">    <span class="keyword">int</span> rightMax=dfs(root.right);</span><br><span class="line">    <span class="keyword">if</span>(root.left!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="comment">//不相等就直接设置成0</span></span><br><span class="line">        leftMax=root.left.val==root.val?leftMax+<span class="number">1</span>:<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root.right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        rightMax=root.right.val==root.val?rightMax+<span class="number">1</span>:<span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//其实3种情况都包含了</span></span><br><span class="line">    res=Math.max(res,leftMax+rightMax);</span><br><span class="line">    <span class="keyword">return</span> Math.max(leftMax,rightMax);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>注意dfs函数的定义：<em><strong>以root开头的最长同值路径</strong></em></p>
<p>既然是以root开头，所以代表的其实是<strong>单侧</strong>的最长路径，也就是说这个路径不能穿过root，所以我们要分别求左右的值，然后取最大值，再判断和左右节点是否相等</p>
<p>再然后我们需要判断root和左右节点值是否相等，如果和左右节点不想等，那么<code>leftMax</code>和<code>rightMax</code>应该直接置为0，不应该再代入做计算，上面的错误解法就是错在这里，如果相等那就应该+1，然后统计最大值的时候也就可以很轻松的包含所有的3种情况</p>
<blockquote>
<p>这里为什么要先求最大值，再判断，先判断在求最大值不行么？</p>
<p>其实想想就知道不行，先判断其实相当于<code>前序遍历</code>，在访问节点第一次的时候如果不符合条件就直接返回了，这样根本无法遍历完所有的节点自然是不行，所以这种类型的一般都是<code>后序遍历</code>，待子节点都处理完之后再返回根节点做处理，和分治的思想很像</p>
</blockquote>
<p><strong>Update: 2020.6.21</strong></p>
<p>go重写一遍，换了个方式，统计节点个数最后减一</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">longestUnivaluePath</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> root==<span class="literal">nil</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> Max=<span class="function"><span class="keyword">func</span><span class="params">(a,b <span class="keyword">int</span>)</span><span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> a&gt;b&#123;<span class="keyword">return</span> a&#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> res=<span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span><span class="title">int</span></span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span> <span class="params">(root *TreeNode)</span><span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> root==<span class="literal">nil</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//root和左右子节点能形成的最长同值路径(至少是1)</span></span><br><span class="line">        left := <span class="number">1</span>+dfs(root.Left) </span><br><span class="line">        right := <span class="number">1</span>+dfs(root.Right)</span><br><span class="line">        <span class="keyword">if</span> root.Left==<span class="literal">nil</span> || root.Val!=root.Left.Val&#123;</span><br><span class="line">            left=<span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> root.Right==<span class="literal">nil</span> || root.Val!=root.Right.Val&#123;</span><br><span class="line">            right=<span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        res=Max(res,left+right<span class="number">-1</span>)</span><br><span class="line">        <span class="keyword">return</span> Max(left,right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res<span class="number">-1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>另一种dfs的思路，代码更加简洁一点，但是稍微有一点不好想</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestUnivaluePath</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="comment">//起点的值无所谓,root节点没有父节点不用向上层函数返回值</span></span><br><span class="line">    dfs(root,-<span class="number">1</span>); </span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//以 root父节点和root 开始的同值路径长度</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root,<span class="keyword">int</span> parent)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> leftMax=dfs(root.left,root.val);</span><br><span class="line">    <span class="keyword">int</span> rightMax=dfs(root.right,root.val);</span><br><span class="line">    <span class="comment">//这里res的计算其实3种情况都包含了</span></span><br><span class="line">    res=Math.max(res,leftMax+rightMax);</span><br><span class="line">    <span class="keyword">if</span>(root.val==parent)&#123;</span><br><span class="line">        <span class="comment">//和父节点同值,返回左右最大值+1</span></span><br><span class="line">        <span class="keyword">return</span> Math.max(leftMax,rightMax)+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//和父节点不同值，直接返回0</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>注意dfs函数的定义：<em><strong>以node父节点和node开始的同值路径长度</strong></em></p>
<p>在函数中添加一个父节点的值，然后在遍历到一个节点的时候判断当前节点和父节点的关系就行了，如果和父节点不相等，那么直接返回0，相等就返回左右最大值+1（这个+1加的是当前节点），然后同样采用后序遍历，这个思路没有那么自然，不过也挺不错的</p>
<blockquote>
<p>还有一种暴力解法，这里就不贴了</p>
</blockquote>
<h2 id="595-二叉树最长连续序列（LintCode）"><a href="#595-二叉树最长连续序列（LintCode）" class="headerlink" title="595. 二叉树最长连续序列（LintCode）"></a><a class="link"   target="_blank" rel="noopener" href="https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence/description?ordering=-updated_at" >595. 二叉树最长连续序列（LintCode）<i class="fas fa-external-link-alt"></i></a></h2><p><strong>描述</strong></p>
<p>给一棵二叉树，找到最长连续路径的长度。<br>这条路径是指 任何的节点序列中的起始节点到树中的任一节点都必须遵循 父-子 联系。最长的连续路径必须是从父亲节点到孩子节点（<code>不能逆序</code>）。</p>
<p><strong>样例1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">&#123;<span class="number">1</span>,#,<span class="number">3</span>,<span class="number">2</span>,<span class="number">4</span>,#,#,#,<span class="number">5</span>&#125;</span><br><span class="line">输出:<span class="number">3</span></span><br><span class="line">说明:</span><br><span class="line">这棵树如图所示</span><br><span class="line">   <span class="number">1</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">3</span></span><br><span class="line">    / \</span><br><span class="line">   <span class="number">2</span>   <span class="number">4</span></span><br><span class="line">        \</span><br><span class="line">         <span class="number">5</span></span><br><span class="line">最长连续序列是<span class="number">3</span>-<span class="number">4</span>-<span class="number">5</span>，所以返回<span class="number">3.</span></span><br></pre></td></tr></table></figure>

<p><strong>样例2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">&#123;<span class="number">2</span>,#,<span class="number">3</span>,<span class="number">2</span>,#,<span class="number">1</span>,#&#125;</span><br><span class="line">输出:<span class="number">2</span></span><br><span class="line">说明:</span><br><span class="line">这棵树如图所示：</span><br><span class="line">   <span class="number">2</span></span><br><span class="line">    \</span><br><span class="line">     <span class="number">3</span></span><br><span class="line">    / </span><br><span class="line">   <span class="number">2</span>    </span><br><span class="line">  / </span><br><span class="line"> <span class="number">1</span></span><br><span class="line">最长连续序列是<span class="number">2</span>-<span class="number">3</span>，而不是<span class="number">3</span>-<span class="number">2</span>-<span class="number">1</span>，所以返回<span class="number">2.</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>和上一题最长同值路径几乎一摸一样，这题leetCode也有，<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-longest-consecutive-sequence" >但是是会员题<i class="fas fa-external-link-alt"></i></a>，前几天每日一题出了这个（后来改了），然后我在lintcode找到了，应该是同一题，随手做一下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestConsecutive</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// write your code here</span></span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> max;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//以root开始的最长连续序列</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root == <span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//保证至少是1</span></span><br><span class="line">    <span class="keyword">int</span> leftMax = Math.max(<span class="number">1</span>,dfs(root.left));</span><br><span class="line">    <span class="keyword">int</span> rightMax = Math.max(<span class="number">1</span>,dfs(root.right));</span><br><span class="line">    <span class="keyword">if</span>(root.left!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        leftMax = root.val==root.left.val-<span class="number">1</span> ? leftMax+<span class="number">1</span>:<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(root.right!=<span class="keyword">null</span>)&#123;</span><br><span class="line">        rightMax = root.val==root.right.val-<span class="number">1</span> ? rightMax+<span class="number">1</span>:<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    max=Math.max(max,Math.max(leftMax,rightMax));</span><br><span class="line">    <span class="keyword">return</span> Math.max(leftMax,rightMax);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其实一开始写了一个很复杂的，dfs的定义又和父节点耦合了，感觉和父节点耦合之后就很难搞，很容易搞晕，所以尽量不和父节点耦合，直接以当前节点定义</p>
<p><strong>Update: 2020.6.21</strong></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">longestConsecutive</span> <span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span><span class="params">(a,b <span class="keyword">int</span>)</span><span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> a&gt;b&#123;<span class="keyword">return</span> a&#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span></span><br><span class="line">    <span class="keyword">var</span> res=<span class="number">0</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span><span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> root ==<span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">        &#125;</span><br><span class="line">        left:= <span class="number">1</span>+dfs(root.Left)</span><br><span class="line">        right:= <span class="number">1</span>+dfs(root.Right)</span><br><span class="line">        <span class="keyword">if</span> root.Left==<span class="literal">nil</span> ||root.Left.Val!=root.Val+<span class="number">1</span>&#123;</span><br><span class="line">            left=<span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> root.Right==<span class="literal">nil</span> ||root.Right.Val!=root.Val+<span class="number">1</span>&#123;</span><br><span class="line">            right=<span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">        res=Max(res,Max(left,right))</span><br><span class="line">        <span class="keyword">return</span> Max(left,right)</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="337-打家劫舍-III"><a href="#337-打家劫舍-III" class="headerlink" title="337. 打家劫舍 III"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/house-robber-iii/" >337. 打家劫舍 III<i class="fas fa-external-link-alt"></i></a></h2><p>在上次打劫完一条街道之后和一圈房屋后，小偷又发现了一个新的可行窃的地区。这个地区只有一个入口，我们称之为“根”。 除了“根”之外，每栋房子有且只有一个“父“房子与之相连。一番侦察之后，聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫，房屋将自动报警。</p>
<p>计算在不触动警报的情况下，小偷一晚能够盗取的最高金额。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">3</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">1</span>]</span><br><span class="line"> 	 <span class="number">3</span></span><br><span class="line">	/ \</span><br><span class="line">   <span class="number">2</span>   <span class="number">3</span></span><br><span class="line">    \   \ </span><br><span class="line">     <span class="number">3</span>   <span class="number">1</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">7</span> </span><br><span class="line">解释: 小偷一晚能够盗取的最高金额 = <span class="number">3</span> + <span class="number">3</span> + <span class="number">1</span> = <span class="number">7.</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="keyword">null</span>,<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"> 	 <span class="number">3</span></span><br><span class="line">	/ \</span><br><span class="line">   <span class="number">4</span>   <span class="number">5</span></span><br><span class="line">  / \   \ </span><br><span class="line"> <span class="number">1</span>   <span class="number">3</span>   <span class="number">1</span></span><br><span class="line"></span><br><span class="line">输出: <span class="number">9</span></span><br><span class="line">解释: 小偷一晚能够盗取的最高金额 = <span class="number">4</span> + <span class="number">5</span> = <span class="number">9.</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>暴力递归，应该还是写得出来</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//AC了,但是效率很低</span></span><br><span class="line"><span class="comment">//可以用hashMap缓存一下每个节点rob的值,但是没必要</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">rob</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> tryRob(root);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">tryRob</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.left==<span class="keyword">null</span> &amp;&amp; root.right==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> root.val;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//偷取当前节点</span></span><br><span class="line">    <span class="keyword">int</span> res=root.val;</span><br><span class="line">    <span class="keyword">if</span> (root.left!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        res+=tryRob(root.left.left)+tryRob(root.left.right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (root.right!=<span class="keyword">null</span>) &#123;</span><br><span class="line">        res+=tryRob(root.right.left)+tryRob(root.right.right);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//不偷当前节点</span></span><br><span class="line">    <span class="keyword">int</span> res2=<span class="number">0</span>;</span><br><span class="line">    res2=tryRob(root.left)+tryRob(root.right);</span><br><span class="line">    <span class="keyword">return</span> Math.max(res,res2);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>看评论区说是啥树形dp ? 知识盲区了hahaha</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">rob</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span>[] res=tryRob(root);</span><br><span class="line">    <span class="keyword">return</span> Math.max(res[<span class="number">0</span>],res[<span class="number">1</span>]);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//树形dp???</span></span><br><span class="line"><span class="comment">//看的懂，但是肯定写不出来 。。。。</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] tryRob(TreeNode root) &#123;</span><br><span class="line">    <span class="keyword">int</span>[] dp=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">if</span> (root==<span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> dp;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">int</span>[] left=tryRob(root.left);</span><br><span class="line">    <span class="keyword">int</span>[] right=tryRob(root.right);</span><br><span class="line">    <span class="comment">//不包含当前节点的最大值</span></span><br><span class="line">    dp[<span class="number">0</span>]=Math.max(left[<span class="number">0</span>],left[<span class="number">1</span>])+Math.max(right[<span class="number">0</span>],right[<span class="number">1</span>]);</span><br><span class="line">    <span class="comment">//包含当前节点的最大值</span></span><br><span class="line">    dp[<span class="number">1</span>]=left[<span class="number">0</span>]+right[<span class="number">0</span>]+root.val;</span><br><span class="line">    <span class="keyword">return</span> dp;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><del>不是我吹，就这样的题目，再遇见多少次我都写不出来这样的解（笑</del></p>
<blockquote>
<p>2020.5.10更新，在看了左神的书后，了解到这种其实就是树形DP，所谓的树形DP实际上就是把递推方程搬到了树结构上，按我的理解树形DP很大的特点就是最终的解可能存在于树上每个节点，所以每个节点都是个子问题，可以从子问题推出父问题</p>
</blockquote>
<h2 id="1372-二叉树中的最长交错路径"><a href="#1372-二叉树中的最长交错路径" class="headerlink" title="1372. 二叉树中的最长交错路径"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/longest-zigzag-path-in-a-binary-tree/" >1372. 二叉树中的最长交错路径<i class="fas fa-external-link-alt"></i></a></h2><p>给你一棵以 <code>root</code> 为根的二叉树，二叉树中的交错路径定义如下：</p>
<ul>
<li>选择二叉树中 <strong>任意</strong> 节点和一个方向（左或者右）。</li>
<li>如果前进方向为右，那么移动到当前节点的的右子节点，否则移动到它的左子节点。</li>
<li>改变前进方向：左变右或者右变左。</li>
<li>重复第二步和第三步，直到你在树中无法继续移动。</li>
</ul>
<p>交错路径的长度定义为：<strong>访问过的节点数目 - 1</strong>（单个节点的路径长度为 0 ）。</p>
<p>请你返回给定树中最长 <strong>交错路径</strong> 的长度。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/22/YX1tJO.png"
                      alt="YX1tJO.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：蓝色节点为树中最长交错路径（右 -&gt; 左 -&gt; 右）。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/22/YX1NWD.png"
                      alt="YX1NWD.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="keyword">null</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="keyword">null</span>,<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">4</span></span><br><span class="line">解释：蓝色节点为树中最长交错路径（左 -&gt; 右 -&gt; 左 -&gt; 右）。</span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：root = [<span class="number">1</span>]</span><br><span class="line">输出：<span class="number">0</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>每棵树最多有 <code>50000</code> 个节点。</li>
<li>每个节点的值在 <code>[1, 100]</code> 之间。</li>
</ul>
<p><strong>解法一</strong></p>
<p>某次周赛的T3，树形DP</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestZigZag</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    dfs(root);</span><br><span class="line">    <span class="keyword">return</span> max-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//当前节点左右交错路径的长度</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] dfs(TreeNode root)&#123;</span><br><span class="line">    <span class="keyword">int</span>[] res=<span class="keyword">new</span> <span class="keyword">int</span>[<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    res[<span class="number">0</span>]=dfs(root.left)[<span class="number">1</span>]+<span class="number">1</span>;</span><br><span class="line">    res[<span class="number">1</span>]=dfs(root.right)[<span class="number">0</span>]+<span class="number">1</span>;</span><br><span class="line">    max=Math.max(max,Math.max(res[<span class="number">0</span>],res[<span class="number">1</span>]));</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>Update: 2020.6.21</strong></p>
<p>用go重写（回顾）下</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">longestZigZag</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span><span class="params">(a,b <span class="keyword">int</span>)</span><span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> a&gt;b&#123;<span class="keyword">return</span> a&#125;</span><br><span class="line">        <span class="keyword">return</span> b</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span>[]<span class="title">int</span></span></span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span>[]<span class="title">int</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> root==<span class="literal">nil</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> []<span class="keyword">int</span>&#123;<span class="number">0</span>,<span class="number">0</span>&#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//0：向左走最长交错 1：向右最长交错路径</span></span><br><span class="line">        left := dfs(root.Left)</span><br><span class="line">        right := dfs(root.Right)</span><br><span class="line">        res=Max(res,Max(left[<span class="number">1</span>]+<span class="number">1</span>,right[<span class="number">0</span>]+<span class="number">1</span>))</span><br><span class="line">        <span class="keyword">return</span> []<span class="keyword">int</span>&#123;left[<span class="number">1</span>]+<span class="number">1</span>,right[<span class="number">0</span>]+<span class="number">1</span>&#125;</span><br><span class="line">    &#125;</span><br><span class="line">    dfs(root)</span><br><span class="line">    <span class="keyword">return</span> res<span class="number">-1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>直接搜索的做法，其实这种做法没有上面树形dp好理解，dfs函数的定义会和父节点混合</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">longestZigZag</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line">    dfs(root,<span class="keyword">false</span>);<span class="comment">//true false都无所谓，root没有父节点</span></span><br><span class="line">    <span class="keyword">return</span> res-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//当前节点和父节点形成的交错路径长度，isRight代表父节点到当前节点的走向是不是right</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">dfs</span><span class="params">(TreeNode root,<span class="keyword">boolean</span> isRight)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(root==<span class="keyword">null</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> l=dfs(root.left,<span class="keyword">false</span>);</span><br><span class="line">    <span class="keyword">int</span> r=dfs(root.right,<span class="keyword">true</span>);</span><br><span class="line">    res=Math.max(res,Math.max(l+<span class="number">1</span>,r+<span class="number">1</span>));</span><br><span class="line">    <span class="keyword">if</span>(isRight)&#123;</span><br><span class="line">        <span class="keyword">return</span> l+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> r+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="968-监控二叉树"><a href="#968-监控二叉树" class="headerlink" title="968. 监控二叉树"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-tree-cameras/" >968. 监控二叉树<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>给定一个二叉树，我们在树的节点上安装摄像头。</p>
<p>节点上的每个摄影头都可以监视<strong>其父对象、自身及其直接子对象。</strong></p>
<p>计算监控树的所有节点所需的最小摄像头数量。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/09/23/wjBgQ1.png"
                      alt="wjBgQ1.png"
                ></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">0</span>,<span class="number">0</span>,null,<span class="number">0</span>,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">1</span></span><br><span class="line">解释：如图所示，一台摄像头足以监控所有节点。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/09/23/wjBfeK.png"
                      alt="wjBfeK.png"
                ></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">0</span>,<span class="number">0</span>,null,<span class="number">0</span>,null,<span class="number">0</span>,null,null,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：需要至少两个摄像头来监视树的所有节点。 上图显示了摄像头放置的有效位置之一。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li> 给定树的节点数的范围是 <code>[1, 1000]</code>。</li>
<li> 每个节点的值都是 0。</li>
</ol>
<p><strong>解法一</strong></p>
<p>树形DP</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * type TreeNode struct &#123;</span></span><br><span class="line"><span class="comment"> *     Val int</span></span><br><span class="line"><span class="comment"> *     Left *TreeNode</span></span><br><span class="line"><span class="comment"> *     Right *TreeNode</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">//0: 覆盖整棵树，root必须设置监控</span></span><br><span class="line"><span class="comment">//1: 覆盖整棵树，无论root是否设置监控</span></span><br><span class="line"><span class="comment">//2: 覆盖两颗子树，无论root是否被覆盖</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">minCameraCover</span><span class="params">(root *TreeNode)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> Min = <span class="function"><span class="keyword">func</span><span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;<span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> a&#125;; <span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="keyword">var</span> INF = <span class="number">0x3f3f3f3f</span></span><br><span class="line">    <span class="keyword">var</span> dfs <span class="function"><span class="keyword">func</span><span class="params">(root *TreeNode)</span> [3]<span class="title">int</span></span> </span><br><span class="line">    dfs = <span class="function"><span class="keyword">func</span> <span class="params">(root *TreeNode)</span> [3]<span class="title">int</span></span> &#123;</span><br><span class="line">        <span class="keyword">var</span> res [<span class="number">3</span>]<span class="keyword">int</span></span><br><span class="line">        <span class="keyword">if</span> root == <span class="literal">nil</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> [<span class="number">3</span>]<span class="keyword">int</span>&#123;INF, <span class="number">0</span>, <span class="number">0</span>&#125;</span><br><span class="line">        &#125;</span><br><span class="line">        left := dfs(root.Left)</span><br><span class="line">        right := dfs(root.Right)</span><br><span class="line">        res[<span class="number">0</span>] = left[<span class="number">2</span>] + right[<span class="number">2</span>] + <span class="number">1</span></span><br><span class="line">        res[<span class="number">1</span>] = Min(res[<span class="number">0</span>], Min(left[<span class="number">0</span>]+right[<span class="number">1</span>], left[<span class="number">1</span>]+right[<span class="number">0</span>]))</span><br><span class="line">        res[<span class="number">2</span>] = Min(res[<span class="number">0</span>], left[<span class="number">1</span>] + right[<span class="number">1</span>])</span><br><span class="line">        <span class="keyword">return</span> res</span><br><span class="line">    &#125;</span><br><span class="line">    r := dfs(root)</span><br><span class="line">    <span class="keyword">return</span> r[<span class="number">1</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="树状数组（BIT）"><a href="#树状数组（BIT）" class="headerlink" title="树状数组（BIT）"></a><em>树状数组（BIT）</em></h2><p>暂时先放在这里，等以后累计多了再单独开辟专题</p>
<h2 id="315-计算右侧小于当前元素的个数"><a href="#315-计算右侧小于当前元素的个数" class="headerlink" title="315. 计算右侧小于当前元素的个数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/" >315. 计算右侧小于当前元素的个数<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>给定一个整数数组 <em>nums_，按要求返回一个新数组 _counts_。数组 _counts</em> 有该性质： <code>counts[i]</code> 的值是  <code>nums[i]</code> 右侧小于 <code>nums[i]</code> 的元素的数量。</p>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">5</span>,<span class="number">2</span>,<span class="number">6</span>,<span class="number">1</span>]</span><br><span class="line">输出：[<span class="number">2</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>] </span><br><span class="line">解释：</span><br><span class="line"><span class="number">5</span> 的右侧有 <span class="number">2</span> 个更小的元素 (<span class="number">2</span> 和 <span class="number">1</span>)</span><br><span class="line"><span class="number">2</span> 的右侧仅有 <span class="number">1</span> 个更小的元素 (<span class="number">1</span>)</span><br><span class="line"><span class="number">6</span> 的右侧有 <span class="number">1</span> 个更小的元素 (<span class="number">1</span>)</span><br><span class="line"><span class="number">1</span> 的右侧有 <span class="number">0</span> 个更小的元素</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>0 &lt;= nums.length &lt;= 10^5</code></li>
<li>  <code>-10^4 &lt;= nums[i] &lt;= 10^4</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>这题有<a href="http://imlgw.top/2019/05/04/leetcode-shu-zu/#315-%E8%AE%A1%E7%AE%97%E5%8F%B3%E4%BE%A7%E5%B0%8F%E4%BA%8E%E5%BD%93%E5%89%8D%E5%85%83%E7%B4%A0%E7%9A%84%E4%B8%AA%E6%95%B0">更好的做法</a>，直接归并就行了，这里主要是为了学习BIT</p>
<p>暴力的做法: 其实就是桶排序的思想，我们从右向左扫数组，扫描一个就在对应的桶+1，同时计算该位置左边的前缀和，就是右边比当前元素小的值，也就是我们需要的结果，但是问题是这个<code>bit</code>数组是一直在变化的，扫描一个元素就会在bit数组对应的位置上+1，每次变化后都需要O(N)来重新计算后缀和，这样整体的复杂度就是O(N^2)，数据量1e5，过不了OJ</p>
<p>所以我们可以用线段树来维护区间和，但是线段树代码量比较大，常数也比较大，所以这里学一下新科技：**<a class="link"   target="_blank" rel="noopener" href="https://blog.csdn.net/Yaokai_AssultMaster/article/details/79492190" >树状数组<i class="fas fa-external-link-alt"></i></a>**，区间查询，单点修改时间复杂度都是logN，且代码简单。</p>
<p>同时还有一个问题，这里我们直接按照值来定位是不合适的，数据范围比较大，直接按照元素值来定位会造成很大空间的浪费，并且题目也不允许开这么大的空间，所以还需要离散化，因为我们只关系元素之间的大小关系，所以我们转换成每个元素说对应的rank就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">int</span>[] tree;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> n = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lowbit</span><span class="params">(<span class="keyword">int</span> i)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> i &amp; -i;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//update索引i位置</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">update</span><span class="params">(<span class="keyword">int</span> i, <span class="keyword">int</span> delta)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (i &lt;= n) &#123;</span><br><span class="line">        tree[i] += delta;</span><br><span class="line">        i += lowbit(i);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">query</span><span class="params">(<span class="keyword">int</span> i)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> sum = <span class="number">0</span>;</span><br><span class="line">    <span class="comment">//从1开始</span></span><br><span class="line">    <span class="keyword">while</span> (i &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        sum += tree[i];</span><br><span class="line">        i -= lowbit(i);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">暴力的做法: 其实就是桶排序的思想，我们从右向左扫数组，扫描一个就在对应的桶+1，</span></span><br><span class="line"><span class="comment">同时计算该位置左边的前缀和，就是右边比当前元素小的值，也就是我们需要的结果，</span></span><br><span class="line"><span class="comment">但是问题是这个`bit`数组是一直在变化的，扫描一个元素就会在bit数组对应的位置上+1，</span></span><br><span class="line"><span class="comment">每次变化后都需要O(N)来重新计算后缀和，这样整体的复杂度就是O(N^2)，数据量1e5，过不了OJ</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">所以我们可以用线段树来维护区间和，但是线段树代码量比较大，常数也比较大</span></span><br><span class="line"><span class="comment">所以这里学一下新科技：**树状数组**，区间查询，单点修改时间复杂度都是logN，且代码简单。</span></span><br><span class="line"><span class="comment">同时还有一个问题，这里我们直接按照值来定位是不合适的，数据范围比较大，</span></span><br><span class="line"><span class="comment">直接按照元素值来定位会造成很大空间的浪费，并且题目也不允许开这么大的空间</span></span><br><span class="line"><span class="comment">所以还需要离散化，因为我们只关系元素之间的大小关系，所以我们转换成每个元素说对应的rank就行了</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">countSmaller</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    n = nums.length;</span><br><span class="line">    tree = <span class="keyword">new</span> <span class="keyword">int</span>[n+<span class="number">1</span>];</span><br><span class="line">    List&lt;Integer&gt; res = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line">    <span class="keyword">int</span>[] rank = <span class="keyword">new</span> <span class="keyword">int</span>[n];</span><br><span class="line">    <span class="comment">//temp[0]: index temp[1]: val</span></span><br><span class="line">    <span class="keyword">int</span>[][] temp = <span class="keyword">new</span> <span class="keyword">int</span>[n][<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        temp[i] = <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;i, nums[i]&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//离散化</span></span><br><span class="line">    Arrays.sort(temp, (t1, t2) -&gt; t1[<span class="number">1</span>]-t2[<span class="number">1</span>]);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        rank[temp[i][<span class="number">0</span>]] = i+<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = n-<span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        <span class="comment">//O(NlogN)构建BIT(可以优化成O(N))</span></span><br><span class="line">        update(rank[i], <span class="number">1</span>);</span><br><span class="line">        res.add(<span class="number">0</span>, query(rank[i]-<span class="number">1</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
        </div>

        
            <div class="post-copyright-info">
                <div class="article-copyright-info-container">
    <ul>
        <li>本文标题：LeetCode二叉树</li>
        <li>本文作者：Resolmi</li>
        <li>创建时间：2019-11-06 00:00:00</li>
        <li>
            本文链接：https://imlgw.top/2019/11/06/43c532c9/
        </li>
        <li>
            版权声明：本博客所有文章除特别声明外，均采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">BY-NC-SA</a> 许可协议。转载请注明出处！
        </li>
    </ul>
</div>

            </div>
        

        
            <div class="article-nav">
                
                    <div class="article-prev">
                        <a class="prev"
                           rel="prev"
                           href="/2019/11/08/a49b5008/"
                        >
                            <span class="left arrow-icon flex-center">
                              <i class="fas fa-chevron-left"></i>
                            </span>
                            <span class="title flex-center">
                                <span class="post-nav-title-item">二分搜索树</span>
                                <span class="post-nav-item">上一篇</span>
                            </span>
                        </a>
                    </div>
                
                
                    <div class="article-next">
                        <a class="next"
                           rel="next"
                           href="/2019/10/10/26679fc/"
                        >
                            <span class="title flex-center">
                                <span class="post-nav-title-item">LeetCode回溯&amp;递归</span>
                                <span class="post-nav-item">下一篇</span>
                            </span>
                            <span class="right arrow-icon flex-center">
                              <i class="fas fa-chevron-right"></i>
                            </span>
                        </a>
                    </div>
                
            </div>
        

        
            <div class="comment-container">
                <div class="comments-container">
    <div id="comment-anchor"></div>
    <div class="comment-area-title">
        <i class="fas fa-comments">&nbsp;评论</i>
    </div>
    

        
            <section class="disqus-comments">
<div id="disqus_thread">
  <noscript>Please enable JavaScript to view the <a target="_blank" rel="noopener" href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</section>

<script>
var disqus_shortname = 'imlgw';

var disqus_url = 'https://imlgw.top/2019/11/06/43c532c9/';

(function(){
  var dsq = document.createElement('script');
  dsq.type = 'text/javascript';
  dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>

<script id="dsq-count-scr" src="//imlgw.disqus.com/count.js" async></script>
        
    
</div>

            </div>
        
    </div>
</div>


                
            </div>

        </div>

        <div class="page-main-content-bottom">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info info-item">
            &copy;
            
              <span>2018</span>&nbsp;-&nbsp;
            
            2021&nbsp;<i class="fas fa-heart icon-animate"></i>&nbsp;<a href="/">Resolmi</a>
        </div>
        
            <script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="website-count info-item">
                
                    <span id="busuanzi_container_site_uv">
                        访问人数&nbsp;<span id="busuanzi_value_site_uv"></span>&ensp;
                    </span>
                
                
                    <span id="busuanzi_container_site_pv">
                        总访问量&nbsp;<span id="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        
            <div class="icp-info info-item"><a target="_blank" rel="nofollow" href="https://beian.miit.gov.cn">鄂ICP备18011208号</a></div>
        
    </div>
</footer>

        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="tools-list">
        <!-- TOC aside toggle -->
        
            <li class="tools-item page-aside-toggle">
                <i class="fas fa-outdent"></i>
            </li>
        

        <!-- go comment -->
        
            <li class="go-comment">
                <i class="fas fa-comment"></i>
            </li>
        
    </ul>
</div>

        </div>
    

    <div class="right-bottom-side-tools">
        <div class="side-tools-container">
    <ul class="side-tools-list">
        <li class="tools-item tool-font-adjust-plus flex-center">
            <i class="fas fa-search-plus"></i>
        </li>

        <li class="tools-item tool-font-adjust-minus flex-center">
            <i class="fas fa-search-minus"></i>
        </li>

        <li class="tools-item tool-expand-width flex-center">
            <i class="fas fa-arrows-alt-h"></i>
        </li>

        <li class="tools-item tool-dark-light-toggle flex-center">
            <i class="fas fa-moon"></i>
        </li>

        <!-- rss -->
        

        

        <li class="tools-item tool-scroll-to-bottom flex-center">
            <i class="fas fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="exposed-tools-list">
        <li class="tools-item tool-toggle-show flex-center">
            <i class="fas fa-cog fa-spin"></i>
        </li>
        
            <li class="tools-item tool-scroll-to-top flex-center">
                <i class="arrow-up fas fa-arrow-up"></i>
                <span class="percent"></span>
            </li>
        
    </ul>
</div>

    </div>

    
        <aside class="page-aside">
            <div class="post-toc-wrap">
    <div class="post-toc">
        <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#LeetCode-%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">1.</span> <span class="nav-text">LeetCode 二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#144-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86"><span class="nav-number">2.</span> <span class="nav-text">144. 二叉树的前序遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#589-N%E5%8F%89%E6%A0%91%E7%9A%84%E5%89%8D%E5%BA%8F%E9%81%8D%E5%8E%86"><span class="nav-number">3.</span> <span class="nav-text">589. N叉树的前序遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#94-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86"><span class="nav-number">4.</span> <span class="nav-text">94. 二叉树的中序遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#145-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86"><span class="nav-number">5.</span> <span class="nav-text">145. 二叉树的后序遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#590-N%E5%8F%89%E6%A0%91%E7%9A%84%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86"><span class="nav-number">6.</span> <span class="nav-text">590. N叉树的后序遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#102-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E6%AC%A1%E9%81%8D%E5%8E%86"><span class="nav-number">7.</span> <span class="nav-text">102. 二叉树的层次遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#429-N%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E5%BA%8F%E9%81%8D%E5%8E%86"><span class="nav-number">8.</span> <span class="nav-text">429. N叉树的层序遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#107-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E6%AC%A1%E9%81%8D%E5%8E%86-II"><span class="nav-number">9.</span> <span class="nav-text">107. 二叉树的层次遍历 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#103-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%94%AF%E9%BD%BF%E5%BD%A2%E5%B1%82%E6%AC%A1%E9%81%8D%E5%8E%86"><span class="nav-number">10.</span> <span class="nav-text">103. 二叉树的锯齿形层次遍历</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#199-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%8F%B3%E8%A7%86%E5%9B%BE"><span class="nav-number">11.</span> <span class="nav-text">199. 二叉树的右视图</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#637-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E5%B9%B3%E5%9D%87%E5%80%BC"><span class="nav-number">12.</span> <span class="nav-text">637. 二叉树的层平均值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#104-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6"><span class="nav-number">13.</span> <span class="nav-text">104. 二叉树的最大深度</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#559-N%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6"><span class="nav-number">14.</span> <span class="nav-text">559. N叉树的最大深度</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#111-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E6%B7%B1%E5%BA%A6"><span class="nav-number">15.</span> <span class="nav-text">111. 二叉树的最小深度</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#226-%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">16.</span> <span class="nav-text">226. 翻转二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#100-%E7%9B%B8%E5%90%8C%E7%9A%84%E6%A0%91"><span class="nav-number">17.</span> <span class="nav-text">100. 相同的树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#951-%E7%BF%BB%E8%BD%AC%E7%AD%89%E4%BB%B7%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">18.</span> <span class="nav-text">951. 翻转等价二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#572-%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%A0%91%E7%9A%84%E5%AD%90%E6%A0%91"><span class="nav-number">19.</span> <span class="nav-text">572. 另一个树的子树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%9826-%E6%A0%91%E7%9A%84%E5%AD%90%E7%BB%93%E6%9E%84"><span class="nav-number">20.</span> <span class="nav-text">面试题26. 树的子结构</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#222-%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E8%8A%82%E7%82%B9%E4%B8%AA%E6%95%B0"><span class="nav-number">21.</span> <span class="nav-text">222. 完全二叉树的节点个数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#112-%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C"><span class="nav-number">22.</span> <span class="nav-text">112. 路径总和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#404-%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C"><span class="nav-number">23.</span> <span class="nav-text">404. 左叶子之和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#257-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE%84"><span class="nav-number">24.</span> <span class="nav-text">257. 二叉树的所有路径</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#113-%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C-II"><span class="nav-number">25.</span> <span class="nav-text">113. 路径总和 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#894-%E6%89%80%E6%9C%89%E5%8F%AF%E8%83%BD%E7%9A%84%E6%BB%A1%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">26.</span> <span class="nav-text">894. 所有可能的满二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#129-%E6%B1%82%E6%A0%B9%E5%88%B0%E5%8F%B6%E5%AD%90%E8%8A%82%E7%82%B9%E6%95%B0%E5%AD%97%E4%B9%8B%E5%92%8C"><span class="nav-number">27.</span> <span class="nav-text">129. 求根到叶子节点数字之和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1022-%E4%BB%8E%E6%A0%B9%E5%88%B0%E5%8F%B6%E7%9A%84%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%E4%B9%8B%E5%92%8C"><span class="nav-number">28.</span> <span class="nav-text">1022. 从根到叶的二进制数之和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#437-%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C-III"><span class="nav-number">29.</span> <span class="nav-text">437. 路径总和 III</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#235-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88"><span class="nav-number">30.</span> <span class="nav-text">235. 二叉搜索树的最近公共祖先</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#98-%E9%AA%8C%E8%AF%81%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91"><span class="nav-number">31.</span> <span class="nav-text">98. 验证二叉搜索树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#958-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%AE%8C%E5%85%A8%E6%80%A7%E6%A3%80%E9%AA%8C"><span class="nav-number">32.</span> <span class="nav-text">958. 二叉树的完全性检验</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#108-%E5%B0%86%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91"><span class="nav-number">33.</span> <span class="nav-text">108. 将有序数组转换为二叉搜索树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#109-%E6%9C%89%E5%BA%8F%E9%93%BE%E8%A1%A8%E8%BD%AC%E6%8D%A2%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91"><span class="nav-number">34.</span> <span class="nav-text">109. 有序链表转换二叉搜索树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#230-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%AC%ACK%E5%B0%8F%E7%9A%84%E5%85%83%E7%B4%A0"><span class="nav-number">35.</span> <span class="nav-text">230. 二叉搜索树中第K小的元素</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#236-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88"><span class="nav-number">36.</span> <span class="nav-text">236. 二叉树的最近公共祖先</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#101-%E5%AF%B9%E7%A7%B0%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">37.</span> <span class="nav-text">101. 对称二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#513-%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC"><span class="nav-number">38.</span> <span class="nav-text">513. 找树左下角的值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#105-%E4%BB%8E%E5%89%8D%E5%BA%8F%E4%B8%8E%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">39.</span> <span class="nav-text">105. 从前序与中序遍历序列构造二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#106-%E4%BB%8E%E4%B8%AD%E5%BA%8F%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">40.</span> <span class="nav-text">106. 从中序与后序遍历序列构造二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#889-%E6%A0%B9%E6%8D%AE%E5%89%8D%E5%BA%8F%E5%92%8C%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">41.</span> <span class="nav-text">889. 根据前序和后序遍历构造二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#114-%E4%BA%8C%E5%8F%89%E6%A0%91%E5%B1%95%E5%BC%80%E4%B8%BA%E9%93%BE%E8%A1%A8"><span class="nav-number">42.</span> <span class="nav-text">114. 二叉树展开为链表</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%9836-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%8E%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8"><span class="nav-number">43.</span> <span class="nav-text">面试题36. 二叉搜索树与双向链表</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#116-%E5%A1%AB%E5%85%85%E6%AF%8F%E4%B8%AA%E8%8A%82%E7%82%B9%E7%9A%84%E4%B8%8B%E4%B8%80%E4%B8%AA%E5%8F%B3%E4%BE%A7%E8%8A%82%E7%82%B9%E6%8C%87%E9%92%88"><span class="nav-number">44.</span> <span class="nav-text">116. 填充每个节点的下一个右侧节点指针</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#117-%E5%A1%AB%E5%85%85%E6%AF%8F%E4%B8%AA%E8%8A%82%E7%82%B9%E7%9A%84%E4%B8%8B%E4%B8%80%E4%B8%AA%E5%8F%B3%E4%BE%A7%E8%8A%82%E7%82%B9%E6%8C%87%E9%92%88-II"><span class="nav-number">45.</span> <span class="nav-text">117. 填充每个节点的下一个右侧节点指针 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#450-%E5%88%A0%E9%99%A4%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9"><span class="nav-number">46.</span> <span class="nav-text">450. 删除二叉搜索树中的节点</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#701-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%8F%92%E5%85%A5%E6%93%8D%E4%BD%9C"><span class="nav-number">47.</span> <span class="nav-text">701. 二叉搜索树中的插入操作</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#662-%E4%BA%8C%E5%8F%89%E6%A0%91%E6%9C%80%E5%A4%A7%E5%AE%BD%E5%BA%A6"><span class="nav-number">48.</span> <span class="nav-text">662. 二叉树最大宽度</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#671-%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%AD%E7%AC%AC%E4%BA%8C%E5%B0%8F%E7%9A%84%E8%8A%82%E7%82%B9"><span class="nav-number">49.</span> <span class="nav-text">671. 二叉树中第二小的节点</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#938-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E8%8C%83%E5%9B%B4%E5%92%8C"><span class="nav-number">50.</span> <span class="nav-text">938. 二叉搜索树的范围和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#617-%E5%90%88%E5%B9%B6%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">51.</span> <span class="nav-text">617. 合并二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#530-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E5%B7%AE"><span class="nav-number">52.</span> <span class="nav-text">530. 二叉搜索树的最小绝对差</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#501-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E4%BC%97%E6%95%B0"><span class="nav-number">53.</span> <span class="nav-text">501. 二叉搜索树中的众数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#515-%E5%9C%A8%E6%AF%8F%E4%B8%AA%E6%A0%91%E8%A1%8C%E4%B8%AD%E6%89%BE%E6%9C%80%E5%A4%A7%E5%80%BC"><span class="nav-number">54.</span> <span class="nav-text">515. 在每个树行中找最大值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#173-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E8%BF%AD%E4%BB%A3%E5%99%A8"><span class="nav-number">55.</span> <span class="nav-text">173. 二叉搜索树迭代器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#95-%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91-II"><span class="nav-number">56.</span> <span class="nav-text">95. 不同的二叉搜索树 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#538-%E6%8A%8A%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E8%BD%AC%E6%8D%A2%E4%B8%BA%E7%B4%AF%E5%8A%A0%E6%A0%91"><span class="nav-number">57.</span> <span class="nav-text">538. 把二叉搜索树转换为累加树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#508-%E5%87%BA%E7%8E%B0%E6%AC%A1%E6%95%B0%E6%9C%80%E5%A4%9A%E7%9A%84%E5%AD%90%E6%A0%91%E5%85%83%E7%B4%A0%E5%92%8C"><span class="nav-number">58.</span> <span class="nav-text">508. 出现次数最多的子树元素和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#606-%E6%A0%B9%E6%8D%AE%E4%BA%8C%E5%8F%89%E6%A0%91%E5%88%9B%E5%BB%BA%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="nav-number">59.</span> <span class="nav-text">606. 根据二叉树创建字符串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1315-%E7%A5%96%E7%88%B6%E8%8A%82%E7%82%B9%E5%80%BC%E4%B8%BA%E5%81%B6%E6%95%B0%E7%9A%84%E8%8A%82%E7%82%B9%E5%92%8C"><span class="nav-number">60.</span> <span class="nav-text">1315. 祖父节点值为偶数的节点和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1026-%E8%8A%82%E7%82%B9%E4%B8%8E%E5%85%B6%E7%A5%96%E5%85%88%E4%B9%8B%E9%97%B4%E7%9A%84%E6%9C%80%E5%A4%A7%E5%B7%AE%E5%80%BC"><span class="nav-number">61.</span> <span class="nav-text">1026. 节点与其祖先之间的最大差值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1325-%E5%88%A0%E9%99%A4%E7%BB%99%E5%AE%9A%E5%80%BC%E7%9A%84%E5%8F%B6%E5%AD%90%E8%8A%82%E7%82%B9"><span class="nav-number">62.</span> <span class="nav-text">1325. 删除给定值的叶子节点</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1305-%E4%B8%A4%E6%A3%B5%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E5%85%83%E7%B4%A0"><span class="nav-number">63.</span> <span class="nav-text">1305. 两棵二叉搜索树中的所有元素</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1339-%E5%88%86%E8%A3%82%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E4%B9%98%E7%A7%AF"><span class="nav-number">64.</span> <span class="nav-text">1339. 分裂二叉树的最大乘积</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#297-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96%E4%B8%8E%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96"><span class="nav-number">65.</span> <span class="nav-text">297. 二叉树的序列化与反序列化</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#449-%E5%BA%8F%E5%88%97%E5%8C%96%E5%92%8C%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91"><span class="nav-number">66.</span> <span class="nav-text">449. 序列化和反序列化二叉搜索树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%9833-%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97"><span class="nav-number">67.</span> <span class="nav-text">面试题33. 二叉搜索树的后序遍历序列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#654-%E6%9C%80%E5%A4%A7%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">68.</span> <span class="nav-text">654. 最大二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#998-%E6%9C%80%E5%A4%A7%E4%BA%8C%E5%8F%89%E6%A0%91-II"><span class="nav-number">69.</span> <span class="nav-text">998. 最大二叉树 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#652-%E5%AF%BB%E6%89%BE%E9%87%8D%E5%A4%8D%E7%9A%84%E5%AD%90%E6%A0%91"><span class="nav-number">70.</span> <span class="nav-text">652. 寻找重复的子树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#653-%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C-IV-%E8%BE%93%E5%85%A5-BST"><span class="nav-number">71.</span> <span class="nav-text">653. 两数之和 IV - 输入 BST</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#872-%E5%8F%B6%E5%AD%90%E7%9B%B8%E4%BC%BC%E7%9A%84%E6%A0%91"><span class="nav-number">72.</span> <span class="nav-text">872. 叶子相似的树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5398-%E7%BB%9F%E8%AE%A1%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%AD%E5%A5%BD%E8%8A%82%E7%82%B9%E7%9A%84%E6%95%B0%E7%9B%AE"><span class="nav-number">73.</span> <span class="nav-text">5398. 统计二叉树中好节点的数目</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#669-%E4%BF%AE%E5%89%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91"><span class="nav-number">74.</span> <span class="nav-text">669. 修剪二叉搜索树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#814-%E4%BA%8C%E5%8F%89%E6%A0%91%E5%89%AA%E6%9E%9D"><span class="nav-number">75.</span> <span class="nav-text">814. 二叉树剪枝</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#965-%E5%8D%95%E5%80%BC%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">76.</span> <span class="nav-text">965. 单值二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1145-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9D%80%E8%89%B2%E6%B8%B8%E6%88%8F"><span class="nav-number">77.</span> <span class="nav-text">1145. 二叉树着色游戏</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#993-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%A0%82%E5%85%84%E5%BC%9F%E8%8A%82%E7%82%B9"><span class="nav-number">78.</span> <span class="nav-text">993. 二叉树的堂兄弟节点</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#440-%E5%AD%97%E5%85%B8%E5%BA%8F%E7%9A%84%E7%AC%ACK%E5%B0%8F%E6%95%B0%E5%AD%97"><span class="nav-number">79.</span> <span class="nav-text">440. 字典序的第K小数字</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#386-%E5%AD%97%E5%85%B8%E5%BA%8F%E6%8E%92%E6%95%B0"><span class="nav-number">80.</span> <span class="nav-text">386. 字典序排数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1028-%E4%BB%8E%E5%85%88%E5%BA%8F%E9%81%8D%E5%8E%86%E8%BF%98%E5%8E%9F%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">81.</span> <span class="nav-text">1028. 从先序遍历还原二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#897-%E9%80%92%E5%A2%9E%E9%A1%BA%E5%BA%8F%E6%9F%A5%E6%89%BE%E6%A0%91"><span class="nav-number">82.</span> <span class="nav-text">897. 递增顺序查找树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#979-%E5%9C%A8%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%AD%E5%88%86%E9%85%8D%E7%A1%AC%E5%B8%81"><span class="nav-number">83.</span> <span class="nav-text">979. 在二叉树中分配硬币</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#99-%E6%81%A2%E5%A4%8D%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91"><span class="nav-number">84.</span> <span class="nav-text">99. 恢复二叉搜索树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1302-%E5%B1%82%E6%95%B0%E6%9C%80%E6%B7%B1%E5%8F%B6%E5%AD%90%E8%8A%82%E7%82%B9%E7%9A%84%E5%92%8C"><span class="nav-number">85.</span> <span class="nav-text">1302. 层数最深叶子节点的和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A0%91%E5%BD%A2DP-%E5%A4%A7%E6%A6%82"><span class="nav-number">86.</span> <span class="nav-text">树形DP(大概)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#110-%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">87.</span> <span class="nav-text">110. 平衡二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#563-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%9D%A1%E5%BA%A6"><span class="nav-number">88.</span> <span class="nav-text">563. 二叉树的坡度</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#543-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E7%9B%B4%E5%BE%84"><span class="nav-number">89.</span> <span class="nav-text">543. 二叉树的直径</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#124-%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%AD%E7%9A%84%E6%9C%80%E5%A4%A7%E8%B7%AF%E5%BE%84%E5%92%8C"><span class="nav-number">90.</span> <span class="nav-text">124. 二叉树中的最大路径和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#687-%E6%9C%80%E9%95%BF%E5%90%8C%E5%80%BC%E8%B7%AF%E5%BE%84"><span class="nav-number">91.</span> <span class="nav-text">687. 最长同值路径</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#595-%E4%BA%8C%E5%8F%89%E6%A0%91%E6%9C%80%E9%95%BF%E8%BF%9E%E7%BB%AD%E5%BA%8F%E5%88%97%EF%BC%88LintCode%EF%BC%89"><span class="nav-number">92.</span> <span class="nav-text">595. 二叉树最长连续序列（LintCode）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#337-%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D-III"><span class="nav-number">93.</span> <span class="nav-text">337. 打家劫舍 III</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1372-%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%AD%E7%9A%84%E6%9C%80%E9%95%BF%E4%BA%A4%E9%94%99%E8%B7%AF%E5%BE%84"><span class="nav-number">94.</span> <span class="nav-text">1372. 二叉树中的最长交错路径</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#968-%E7%9B%91%E6%8E%A7%E4%BA%8C%E5%8F%89%E6%A0%91"><span class="nav-number">95.</span> <span class="nav-text">968. 监控二叉树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84%EF%BC%88BIT%EF%BC%89"><span class="nav-number">96.</span> <span class="nav-text">树状数组（BIT）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#315-%E8%AE%A1%E7%AE%97%E5%8F%B3%E4%BE%A7%E5%B0%8F%E4%BA%8E%E5%BD%93%E5%89%8D%E5%85%83%E7%B4%A0%E7%9A%84%E4%B8%AA%E6%95%B0"><span class="nav-number">97.</span> <span class="nav-text">315. 计算右侧小于当前元素的个数</span></a></li></ol>
    </div>
</div>
        </aside>
    

    <div class="image-viewer-container">
    <img src="">
</div>


    
        <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
          <span class="search-input-field-pre">
            <i class="fas fa-keyboard"></i>
          </span>
            <div class="search-input-container">
                <input autocomplete="off"
                       autocorrect="off"
                       autocapitalize="off"
                       placeholder="搜索..."
                       spellcheck="false"
                       type="search"
                       class="search-input"
                >
            </div>
            <span class="popup-btn-close">
                <i class="fas fa-times"></i>
            </span>
        </div>
        <div id="search-result">
            <div id="no-result">
                <i class="fas fa-spinner fa-pulse fa-5x fa-fw"></i>
            </div>
        </div>
    </div>
</div>

    

</main>



<script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/utils.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/main.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/header-shrink.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/back2top.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/dark-light-toggle.js"></script>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/local-search.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/code-copy.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/lazyload.js"></script>


<div class="post-scripts pjax">
    
        <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/left-side-toggle.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/anime.min.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/toc.js"></script>
    
</div>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/pjax.min.js"></script>
<script>
    window.addEventListener('DOMContentLoaded', () => {
        window.pjax = new Pjax({
            selectors: [
                'head title',
                '.page-container',
                '.pjax'
            ],
            history: true,
            debug: false,
            cacheBust: false,
            timeout: 0,
            analytics: false,
            currentUrlFullReload: false,
            scrollRestoration: false,
            // scrollTo: true,
        });

        document.addEventListener('pjax:send', () => {
            KEEP.utils.pjaxProgressBarStart();
        });

        document.addEventListener('pjax:complete', () => {
            KEEP.utils.pjaxProgressBarEnd();
            window.pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
            KEEP.refresh();
        });
    });
</script>



<script src="https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"https://cdn.jsdelivr.net/npm/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json"},"display":{"superSample":2,"width":160,"height":320,"position":"right","hOffset":0,"vOffset":-70},"mobile":{"show":false,"scale":0.2},"log":false});</script></body>
</html>
